aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-autoroll <android-autoroll@skia-corp.google.com.iam.gserviceaccount.com>2019-04-16 19:54:55 +0000
committerLeon Scroggins <scroggo@google.com>2019-04-17 19:00:55 +0000
commitf77d507089368e8858397bfb71681f00a0aaf69b (patch)
tree0377d84b9cd3f0074f5b04b2be4c1eeae245c56f
parentd2a668b1ddf358b1d04d3a4cf892bdbc3883ce4a (diff)
parent057939b4d61d28d21753f3b22bcdbbcf503001cf (diff)
downloadskia-f77d507089368e8858397bfb71681f00a0aaf69b.tar.gz
RESTRICT AUTOMERGE: Roll external/skia fc6e072bd..057939b4d (1 commits)
https://skia.googlesource.com/skia.git/+log/fc6e072bd..057939b4d 2019-04-16 egdaniel@google.com Cherry-Pick for adding callback to flush for knowing when gpu is finished work. The AutoRoll server is located here: https://autoroll-internal.skia.org/r/android-next-autoroll Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md If the roll is causing failures, please contact the current sheriff, who should be CC'd on the roll, and stop the roller if necessary. Test: Presubmit checks will test this change. Exempt-From-Owner-Approval: The autoroll bot does not require owner approval. Bug: 130643604 Change-Id: Ifb11e6bb703c455b902d9fe7261d0582d1dc50a7
-rw-r--r--Android.bp1
-rw-r--r--gn/tests.gni1
-rw-r--r--include/core/SkSurface.h52
-rw-r--r--include/gpu/GrContext.h25
-rw-r--r--include/gpu/GrTypes.h9
-rw-r--r--src/gpu/GrContext.cpp12
-rw-r--r--src/gpu/GrContextPriv.cpp5
-rw-r--r--src/gpu/GrDrawingManager.cpp38
-rw-r--r--src/gpu/GrDrawingManager.h12
-rw-r--r--src/gpu/GrGpu.cpp9
-rw-r--r--src/gpu/GrGpu.h10
-rw-r--r--src/gpu/GrRenderTargetContext.cpp9
-rw-r--r--src/gpu/GrRenderTargetContext.h6
-rw-r--r--src/gpu/SkGpuDevice.cpp15
-rw-r--r--src/gpu/SkGpuDevice.h10
-rw-r--r--src/gpu/gl/GrGLGpu.cpp10
-rw-r--r--src/gpu/gl/GrGLGpu.h4
-rw-r--r--src/gpu/mock/GrMockGpu.h8
-rw-r--r--src/gpu/mtl/GrMtlGpu.h14
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.cpp9
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h5
-rw-r--r--src/gpu/vk/GrVkGpu.cpp17
-rw-r--r--src/gpu/vk/GrVkGpu.h8
-rw-r--r--src/gpu/vk/GrVkResourceProvider.cpp12
-rw-r--r--src/gpu/vk/GrVkResourceProvider.h7
-rw-r--r--src/image/SkImage_Gpu.cpp2
-rw-r--r--src/image/SkSurface.cpp18
-rw-r--r--src/image/SkSurface_Base.h6
-rw-r--r--src/image/SkSurface_Gpu.cpp13
-rw-r--r--src/image/SkSurface_Gpu.h7
-rw-r--r--tests/DefaultPathRendererTest.cpp2
-rw-r--r--tests/GLProgramsTest.cpp4
-rw-r--r--tests/GrFinishedFlushTest.cpp92
-rw-r--r--tests/OnFlushCallbackTest.cpp2
-rw-r--r--tests/SurfaceSemaphoreTest.cpp2
-rw-r--r--tests/VkHardwareBufferTest.cpp4
-rw-r--r--tools/sk_app/VulkanWindowContext.cpp2
37 files changed, 343 insertions, 119 deletions
diff --git a/Android.bp b/Android.bp
index 273614487c..5bf8970397 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1582,6 +1582,7 @@ cc_test {
"tests/GrCCPRTest.cpp",
"tests/GrContextAbandonTest.cpp",
"tests/GrContextFactoryTest.cpp",
+ "tests/GrFinishedFlushTest.cpp",
"tests/GrGLExtensionsTest.cpp",
"tests/GrMemoryPoolTest.cpp",
"tests/GrMeshTest.cpp",
diff --git a/gn/tests.gni b/gn/tests.gni
index bd7b9b7669..1a46a8df50 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -94,6 +94,7 @@ tests_sources = [
"$_tests/GrCCPRTest.cpp",
"$_tests/GrContextAbandonTest.cpp",
"$_tests/GrContextFactoryTest.cpp",
+ "$_tests/GrFinishedFlushTest.cpp",
"$_tests/GrGLExtensionsTest.cpp",
"$_tests/GrMemoryPoolTest.cpp",
"$_tests/GrMeshTest.cpp",
diff --git a/include/core/SkSurface.h b/include/core/SkSurface.h
index 7e0a85233d..f2ffee735a 100644
--- a/include/core/SkSurface.h
+++ b/include/core/SkSurface.h
@@ -723,12 +723,6 @@ public:
kPresent, //!< back-end surface will be used for presenting to screen
};
- enum FlushFlags {
- kNone_FlushFlags = 0,
- // flush will wait till all submitted GPU work is finished before returning.
- kSyncCpu_FlushFlag = 0x1,
- };
-
/** Issues pending SkSurface commands to the GPU-backed API and resolves any SkSurface MSAA.
After issuing all commands, signalSemaphores of count numSemaphores are signaled by the GPU.
The work that is submitted to the GPU will be dependent on the BackendSurfaceAccess that is
@@ -762,41 +756,35 @@ public:
Pending surface commands are flushed regardless of the return result.
+ If a finishedProc is provided, the finishedProc will be called when all work submitted to
+ the gpu from this flush call and all previous flush calls has finished on the GPU. If the
+ flush call fails due to an error and nothing ends up getting sent to the GPU, the finished
+ proc is called immediately.
+
@param access type of access the call will do on the backend object after flush
@param flags flush options
@param numSemaphores size of signalSemaphores array
@param signalSemaphores array of semaphore containers
+ @param finishedProc proc called after gpu work from flush has finished
+ @param finishedContext context passed into call to finishedProc
@return one of: GrSemaphoresSubmitted::kYes, GrSemaphoresSubmitted::kNo
*/
+ GrSemaphoresSubmitted flush(BackendSurfaceAccess access, GrFlushFlags flags,
+ int numSemaphores, GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc = nullptr,
+ GrGpuFinishedContext finishedContext = nullptr);
+
+ /** The below enum and flush call are deprected
+ */
+ enum FlushFlags {
+ kNone_FlushFlags = 0,
+ // flush will wait till all submitted GPU work is finished before returning.
+ kSyncCpu_FlushFlag = 0x1,
+ };
GrSemaphoresSubmitted flush(BackendSurfaceAccess access, FlushFlags flags,
int numSemaphores, GrBackendSemaphore signalSemaphores[]);
- /** Issues pending SkSurface commands to the GPU-backed API and resolves any SkSurface MSAA.
- After issuing all commands, signalSemaphores of count numSemaphores semaphores
- are signaled by the GPU.
-
- For each GrBackendSemaphore in signalSemaphores:
- if GrBackendSemaphore is initialized, the GPU back-end uses the semaphore as is;
- otherwise, a new semaphore is created and initializes GrBackendSemaphore.
-
- The caller must delete the semaphores created and returned in signalSemaphores.
- GrBackendSemaphore can be deleted as soon as this function returns.
-
- If the back-end API is OpenGL only uninitialized backend semaphores are supported.
-
- If the back-end API is Vulkan semaphores may be initialized or uninitialized.
- If uninitialized, created semaphores are valid only with the VkDevice
- with which they were created.
-
- If GrSemaphoresSubmitted::kNo is returned, the GPU back-end did not create or
- add any semaphores to signal on the GPU; the caller should not instruct the GPU
- to wait on any of the semaphores.
-
- Pending surface commands are flushed regardless of the return result.
-
- @param numSemaphores size of signalSemaphores array
- @param signalSemaphores array of semaphore containers
- @return one of: GrSemaphoresSubmitted::kYes, GrSemaphoresSubmitted::kNo
+ /** Deprecated.
*/
GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
GrBackendSemaphore signalSemaphores[]);
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 09f3ca4483..94f7ccbfba 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -260,16 +260,31 @@ public:
* 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 the backend API is Vulkan either initialized or uninitialized semaphores are supported.
+ * If uninitialized, 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
+ * If this call returns GrSemaphoresSubmitted::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.
+ *
+ * If a finishedProc is provided, the finishedProc will be called when all work submitted to the
+ * gpu from this flush call and all previous flush calls has finished on the GPU. If the flush
+ * call fails due to an error and nothing ends up getting sent to the GPU, the finished proc is
+ * called immediately.
+ */
+ GrSemaphoresSubmitted flush(GrFlushFlags flags, int numSemaphores,
+ GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc = nullptr,
+ GrGpuFinishedContext finishedContext = nullptr);
+
+ /**
+ * Deprecated.
*/
GrSemaphoresSubmitted flushAndSignalSemaphores(int numSemaphores,
- GrBackendSemaphore signalSemaphores[]);
+ GrBackendSemaphore signalSemaphores[]) {
+ return this->flush(kNone_GrFlushFlags, numSemaphores, signalSemaphores);
+ }
// Provides access to functions that aren't part of the public API.
GrContextPriv priv();
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 5005d57a4c..74ad506281 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -259,6 +259,15 @@ enum GrGLBackendState {
*/
static const uint32_t kAll_GrBackendState = 0xffffffff;
+enum GrFlushFlags {
+ kNone_GrFlushFlags = 0,
+ // flush will wait till all submitted GPU work is finished before returning.
+ kSyncCpu_GrFlushFlag = 0x1,
+};
+
+typedef void* GrGpuFinishedContext;
+typedef void (*GrGpuFinishedProc)(GrGpuFinishedContext finishedContext);
+
/**
* Enum used as return value when flush with semaphores so the client knows whether the semaphores
* were submitted to GPU or not.
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 9713beb4b3..94a549be56 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -237,19 +237,21 @@ void GrContext::flush() {
RETURN_IF_ABANDONED
this->drawingManager()->flush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
}
-GrSemaphoresSubmitted GrContext::flushAndSignalSemaphores(int numSemaphores,
- GrBackendSemaphore signalSemaphores[]) {
+GrSemaphoresSubmitted GrContext::flush(GrFlushFlags flags, int numSemaphores,
+ GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
ASSERT_SINGLE_OWNER
if (this->abandoned()) {
return GrSemaphoresSubmitted::kNo;
}
return this->drawingManager()->flush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, numSemaphores,
- signalSemaphores);
+ flags, numSemaphores, signalSemaphores, finishedProc,
+ finishedContext);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index 743b33d342..cdc4ba48cb 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -195,7 +195,7 @@ void GrContextPriv::flush(GrSurfaceProxy* proxy) {
ASSERT_OWNED_PROXY_PRIV(proxy);
fContext->drawingManager()->flush(proxy, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
}
void GrContextPriv::flushSurfaceWrites(GrSurfaceProxy* proxy) {
@@ -224,7 +224,8 @@ void GrContextPriv::prepareSurfaceForExternalIO(GrSurfaceProxy* proxy) {
SkASSERT(proxy);
ASSERT_OWNED_PROXY_PRIV(proxy);
fContext->drawingManager()->prepareSurfaceForExternalIO(proxy,
- SkSurface::BackendSurfaceAccess::kNoAccess, SkSurface::kNone_FlushFlags, 0, nullptr);
+ SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
+ nullptr, nullptr);
}
static bool valid_premul_color_type(GrColorType ct) {
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 10da8f947f..4d147e2e17 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -198,25 +198,37 @@ void GrDrawingManager::freeGpuResources() {
// MDB TODO: make use of the 'proxy' parameter.
GrSemaphoresSubmitted GrDrawingManager::flush(GrSurfaceProxy* proxy,
SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags,
+ GrFlushFlags flags,
int numSemaphores,
- GrBackendSemaphore backendSemaphores[]) {
+ GrBackendSemaphore backendSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
GR_CREATE_TRACE_MARKER_CONTEXT("GrDrawingManager", "flush", fContext);
if (fFlushing || this->wasAbandoned()) {
+ if (finishedProc) {
+ finishedProc(finishedContext);
+ }
return GrSemaphoresSubmitted::kNo;
}
SkDEBUGCODE(this->validate());
auto direct = fContext->priv().asDirectContext();
if (!direct) {
+ if (finishedProc) {
+ finishedProc(finishedContext);
+ }
return GrSemaphoresSubmitted::kNo; // Can't flush while DDL recording
}
GrGpu* gpu = direct->priv().getGpu();
if (!gpu) {
+ if (finishedProc) {
+ finishedProc(finishedContext);
+ }
return GrSemaphoresSubmitted::kNo; // Can't flush while DDL recording
}
+
fFlushing = true;
auto resourceProvider = direct->priv().resourceProvider();
@@ -334,7 +346,8 @@ GrSemaphoresSubmitted GrDrawingManager::flush(GrSurfaceProxy* proxy,
#endif
GrSemaphoresSubmitted result = gpu->finishFlush(proxy, access, flags, numSemaphores,
- backendSemaphores);
+ backendSemaphores, finishedProc,
+ finishedContext);
flushState.deinstantiateProxyTracker()->deinstantiateAllProxies();
@@ -425,7 +438,7 @@ bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushSt
(*numOpListsExecuted)++;
if (*numOpListsExecuted >= kMaxOpListsBeforeFlush) {
flushState->gpu()->finishFlush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
*numOpListsExecuted = 0;
}
}
@@ -443,7 +456,7 @@ bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushSt
(*numOpListsExecuted)++;
if (*numOpListsExecuted >= kMaxOpListsBeforeFlush) {
flushState->gpu()->finishFlush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
*numOpListsExecuted = 0;
}
}
@@ -462,8 +475,10 @@ bool GrDrawingManager::executeOpLists(int startIndex, int stopIndex, GrOpFlushSt
}
GrSemaphoresSubmitted GrDrawingManager::prepareSurfaceForExternalIO(
- GrSurfaceProxy* proxy, SkSurface::BackendSurfaceAccess access, SkSurface::FlushFlags flags,
- int numSemaphores, GrBackendSemaphore backendSemaphores[]) {
+ GrSurfaceProxy* proxy, SkSurface::BackendSurfaceAccess access, GrFlushFlags flags,
+ int numSemaphores, GrBackendSemaphore backendSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
if (this->wasAbandoned()) {
return GrSemaphoresSubmitted::kNo;
}
@@ -483,9 +498,10 @@ GrSemaphoresSubmitted GrDrawingManager::prepareSurfaceForExternalIO(
auto resourceProvider = direct->priv().resourceProvider();
GrSemaphoresSubmitted result = GrSemaphoresSubmitted::kNo;
- if (proxy->priv().hasPendingIO() || numSemaphores ||
- SkToBool(flags & SkSurface::kSyncCpu_FlushFlag)) {
- result = this->flush(proxy, access, flags, numSemaphores, backendSemaphores);
+ if (proxy->priv().hasPendingIO() || numSemaphores || finishedProc ||
+ SkToBool(flags & kSyncCpu_GrFlushFlag)) {
+ result = this->flush(proxy, access, flags, numSemaphores, backendSemaphores,
+ finishedProc, finishedContext);
}
if (!proxy->instantiate(resourceProvider)) {
@@ -745,7 +761,7 @@ void GrDrawingManager::flushIfNecessary() {
auto resourceCache = direct->priv().getResourceCache();
if (resourceCache && resourceCache->requestsFlush()) {
this->flush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
resourceCache->purgeAsNeeded();
}
}
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index 3f2245e241..25b87af46a 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -74,9 +74,11 @@ public:
GrSemaphoresSubmitted prepareSurfaceForExternalIO(GrSurfaceProxy*,
SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags,
+ GrFlushFlags flags,
int numSemaphores,
- GrBackendSemaphore backendSemaphores[]);
+ GrBackendSemaphore backendSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext);
void addOnFlushCallbackObject(GrOnFlushCallbackObject*);
@@ -151,9 +153,11 @@ private:
GrSemaphoresSubmitted flush(GrSurfaceProxy* proxy,
SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags,
+ GrFlushFlags flags,
int numSemaphores,
- GrBackendSemaphore backendSemaphores[]);
+ GrBackendSemaphore backendSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext);
SkDEBUGCODE(void validate() const);
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index fe5bb20433..801ba46b3e 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -398,8 +398,10 @@ int GrGpu::findOrAssignSamplePatternKey(GrRenderTarget* renderTarget, const GrPi
GrSemaphoresSubmitted GrGpu::finishFlush(GrSurfaceProxy* proxy,
SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, int numSemaphores,
- GrBackendSemaphore backendSemaphores[]) {
+ GrFlushFlags flags, int numSemaphores,
+ GrBackendSemaphore backendSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
this->stats()->incNumFinishFlushes();
GrResourceProvider* resourceProvider = fContext->priv().resourceProvider();
@@ -421,7 +423,8 @@ GrSemaphoresSubmitted GrGpu::finishFlush(GrSurfaceProxy* proxy,
}
}
this->onFinishFlush(proxy, access, flags,
- (numSemaphores > 0 && this->caps()->fenceSyncSupport()));
+ (numSemaphores > 0 && this->caps()->fenceSyncSupport()),
+ finishedProc, finishedContext);
return this->caps()->fenceSyncSupport() ? GrSemaphoresSubmitted::kYes
: GrSemaphoresSubmitted::kNo;
}
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index e7d34e7765..08b401a8f8 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -285,8 +285,10 @@ public:
// insert any numSemaphore semaphores on the gpu and set the backendSemaphores to match the
// inserted semaphores.
GrSemaphoresSubmitted finishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, int numSemaphores,
- GrBackendSemaphore backendSemaphores[]);
+ GrFlushFlags flags, int numSemaphores,
+ GrBackendSemaphore backendSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext);
virtual void submit(GrGpuCommandBuffer*) = 0;
@@ -532,7 +534,9 @@ private:
bool canDiscardOutsideDstRect) = 0;
virtual void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, bool insertedSemaphores) = 0;
+ GrFlushFlags flags, bool insertedSemaphores,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) = 0;
#ifdef SK_ENABLE_DUMP_GPU
virtual void onDumpJSON(SkJSONWriter*) const {}
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index f9d41ff2c2..8a8576fdbf 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1714,8 +1714,9 @@ void GrRenderTargetContext::drawDrawable(std::unique_ptr<SkDrawable::GpuDrawHand
}
GrSemaphoresSubmitted GrRenderTargetContext::prepareForExternalIO(
- SkSurface::BackendSurfaceAccess access, SkSurface::FlushFlags flags, int numSemaphores,
- GrBackendSemaphore backendSemaphores[]) {
+ SkSurface::BackendSurfaceAccess access, GrFlushFlags flags, int numSemaphores,
+ GrBackendSemaphore backendSemaphores[], GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
ASSERT_SINGLE_OWNER
if (fContext->priv().abandoned()) {
return GrSemaphoresSubmitted::kNo;
@@ -1726,7 +1727,9 @@ GrSemaphoresSubmitted GrRenderTargetContext::prepareForExternalIO(
return this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get(),
access, flags,
numSemaphores,
- backendSemaphores);
+ backendSemaphores,
+ finishedProc,
+ finishedContext);
}
bool GrRenderTargetContext::waitOnSemaphores(int numSemaphores,
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 4691e94fae..5d89df87b4 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -407,8 +407,10 @@ public:
* if the surface has MSAA it will be resolved.
*/
GrSemaphoresSubmitted prepareForExternalIO(SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, int numSemaphores,
- GrBackendSemaphore backendSemaphores[]);
+ GrFlushFlags flags, int numSemaphores,
+ GrBackendSemaphore backendSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext);
/**
* The next time this GrRenderTargetContext is flushed, the gpu will wait on the passed in
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index eb8b84ad70..5fa9480c9f 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1612,18 +1612,19 @@ void SkGpuDevice::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix, SkC
///////////////////////////////////////////////////////////////////////////////
void SkGpuDevice::flush() {
- this->flushAndSignalSemaphores(SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ this->flush(SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr, nullptr,
+ nullptr);
}
-GrSemaphoresSubmitted SkGpuDevice::flushAndSignalSemaphores(SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags,
- int numSemaphores,
- GrBackendSemaphore signalSemaphores[]) {
+GrSemaphoresSubmitted SkGpuDevice::flush(SkSurface::BackendSurfaceAccess access, GrFlushFlags flags,
+ int numSemaphores, GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
ASSERT_SINGLE_OWNER
return fRenderTargetContext->prepareForExternalIO(access, flags, numSemaphores,
- signalSemaphores);
+ signalSemaphores, finishedProc,
+ finishedContext);
}
bool SkGpuDevice::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index b41b8c894e..2f0e0d0d1b 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -118,10 +118,12 @@ public:
sk_sp<SkSpecialImage> snapBackImage(const SkIRect&) override;
void flush() override;
- GrSemaphoresSubmitted flushAndSignalSemaphores(SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags,
- int numSemaphores,
- GrBackendSemaphore signalSemaphores[]);
+ GrSemaphoresSubmitted flush(SkSurface::BackendSurfaceAccess access,
+ GrFlushFlags flags,
+ int numSemaphores,
+ GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext);
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 9107fd1cd2..af1d250690 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -4267,14 +4267,20 @@ GrGLAttribArrayState* GrGLGpu::HWVertexArrayState::bindInternalVertexArray(GrGLG
}
void GrGLGpu::onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, bool insertedSemaphore) {
+ GrFlushFlags flags, bool insertedSemaphore,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
// If we inserted semaphores during the flush, we need to call GLFlush.
if (insertedSemaphore) {
GL_CALL(Flush());
}
- if (flags & SkSurface::kSyncCpu_FlushFlag) {
+ if (flags & kSyncCpu_GrFlushFlag) {
GL_CALL(Finish());
}
+ // TODO: We should have GL actually wait until the GPU has finished work on the GPU.
+ if (finishedProc) {
+ finishedProc(finishedContext);
+ }
}
void GrGLGpu::submit(GrGpuCommandBuffer* buffer) {
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 497ea89c57..987caf9400 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -290,7 +290,9 @@ private:
void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, bool insertedSemaphores) override;
+ GrFlushFlags flags, bool insertedSemaphores,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) override;
bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
GrSurface* src, GrSurfaceOrigin srcOrigin,
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 5d5a82b6f0..1f24cb94a4 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -107,7 +107,13 @@ private:
void onResolveRenderTarget(GrRenderTarget* target) override { return; }
void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, bool insertedSemaphores) override {}
+ GrFlushFlags flags, bool insertedSemaphores,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) override {
+ if (finishedProc) {
+ finishedProc(finishedContext);
+ }
+ }
GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
int width,
diff --git a/src/gpu/mtl/GrMtlGpu.h b/src/gpu/mtl/GrMtlGpu.h
index e74fe717b5..c539e85eda 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -174,11 +174,21 @@ private:
void onResolveRenderTarget(GrRenderTarget* target) override { return; }
void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, bool insertedSemaphores) override {
- if (flags & SkSurface::kSyncCpu_FlushFlag) {
+ GrFlushFlags flags, bool insertedSemaphores,
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) override {
+ if (flags & kSyncCpu_GrFlushFlag) {
this->submitCommandBuffer(kForce_SyncQueue);
+ if (finishedProc) {
+ finishedProc(finishedContext);
+ }
} else {
this->submitCommandBuffer(kSkip_SyncQueue);
+ // TODO: support finishedProc to actually be called when the GPU is done with the work
+ // and not immediately.
+ if (finishedProc) {
+ finishedProc(finishedContext);
+ }
}
}
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index a96eef1245..8243893de1 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -577,13 +577,15 @@ void GrVkPrimaryCommandBuffer::submitToQueue(
}
SkASSERT(!err);
+ fFinishedProcs.reset();
+
// Destroy the fence
GR_VK_CALL(gpu->vkInterface(), DestroyFence(gpu->device(), fSubmitFence, nullptr));
fSubmitFence = VK_NULL_HANDLE;
}
}
-bool GrVkPrimaryCommandBuffer::finished(const GrVkGpu* gpu) const {
+bool GrVkPrimaryCommandBuffer::finished(const GrVkGpu* gpu) {
SkASSERT(!fIsActive);
if (VK_NULL_HANDLE == fSubmitFence) {
return true;
@@ -592,6 +594,7 @@ bool GrVkPrimaryCommandBuffer::finished(const GrVkGpu* gpu) const {
VkResult err = GR_VK_CALL(gpu->vkInterface(), GetFenceStatus(gpu->device(), fSubmitFence));
switch (err) {
case VK_SUCCESS:
+ fFinishedProcs.reset();
return true;
case VK_NOT_READY:
@@ -606,6 +609,10 @@ bool GrVkPrimaryCommandBuffer::finished(const GrVkGpu* gpu) const {
return false;
}
+void GrVkPrimaryCommandBuffer::addFinishedProc(sk_sp<GrRefCntedCallback> finishedProc) {
+ fFinishedProcs.push_back(std::move(finishedProc));
+}
+
void GrVkPrimaryCommandBuffer::onReleaseResources(GrVkGpu* gpu) {
for (int i = 0; i < fSecondaryCommandBuffers.count(); ++i) {
fSecondaryCommandBuffers[i]->releaseResources(gpu);
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index 86c3c7eaa3..9f3c22a448 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -301,7 +301,9 @@ public:
void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync,
SkTArray<GrVkSemaphore::Resource*>& signalSemaphores,
SkTArray<GrVkSemaphore::Resource*>& waitSemaphores);
- bool finished(const GrVkGpu* gpu) const;
+ bool finished(const GrVkGpu* gpu);
+
+ void addFinishedProc(sk_sp<GrRefCntedCallback> finishedProc);
void recycleSecondaryCommandBuffers();
@@ -324,6 +326,7 @@ private:
SkTArray<GrVkSecondaryCommandBuffer*, true> fSecondaryCommandBuffers;
VkFence fSubmitFence;
+ SkTArray<sk_sp<GrRefCntedCallback>> fFinishedProcs;
typedef GrVkCommandBuffer INHERITED;
};
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 89e942024c..0b6297948c 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -316,12 +316,18 @@ GrGpuTextureCommandBuffer* GrVkGpu::getCommandBuffer(GrTexture* texture, GrSurfa
return fCachedTexCommandBuffer.get();
}
-void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
+void GrVkGpu::submitCommandBuffer(SyncQueue sync, GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
SkASSERT(fCurrentCmdBuffer);
fCurrentCmdBuffer->end(this);
fCmdPool->close();
fCurrentCmdBuffer->submitToQueue(this, fQueue, sync, fSemaphoresToSignal, fSemaphoresToWaitOn);
+ if (finishedProc) {
+ // Make sure this is called after closing the current command pool
+ fResourceProvider.addFinishedProcToActiveCommandBuffers(finishedProc, finishedContext);
+ }
+
// We must delete and drawables that have been waitint till submit for us to destroy.
fDrawables.reset();
@@ -1804,7 +1810,8 @@ void GrVkGpu::addImageMemoryBarrier(const GrVkResource* resource,
}
void GrVkGpu::onFinishFlush(GrSurfaceProxy* proxy, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, bool insertedSemaphore) {
+ GrFlushFlags flags, bool insertedSemaphore,
+ GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext) {
// Submit the current command buffer to the Queue. Whether we inserted semaphores or not does
// not effect what we do here.
if (proxy && access == SkSurface::BackendSurfaceAccess::kPresent) {
@@ -1819,10 +1826,10 @@ void GrVkGpu::onFinishFlush(GrSurfaceProxy* proxy, SkSurface::BackendSurfaceAcce
}
image->prepareForPresent(this);
}
- if (flags & SkSurface::kSyncCpu_FlushFlag) {
- this->submitCommandBuffer(kForce_SyncQueue);
+ if (flags & kSyncCpu_GrFlushFlag) {
+ this->submitCommandBuffer(kForce_SyncQueue, finishedProc, finishedContext);
} else {
- this->submitCommandBuffer(kSkip_SyncQueue);
+ this->submitCommandBuffer(kSkip_SyncQueue, finishedProc, finishedContext);
}
}
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 663229a856..b001c1d19a 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -222,8 +222,9 @@ private:
GrSurfaceOrigin srcOrigin, const SkIRect& srcRect,
const SkIPoint& dstPoint, bool canDiscardOutsideDstRect) override;
- void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access,
- SkSurface::FlushFlags flags, bool insertedSemaphores) override;
+ void onFinishFlush(GrSurfaceProxy*, SkSurface::BackendSurfaceAccess access, GrFlushFlags flags,
+ bool insertedSemaphores, GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) 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
@@ -231,7 +232,8 @@ private:
// fSemaphoreToSignal, we will add those signal semaphores to the submission of this command
// buffer. If this GrVkGpu object has any semaphores in fSemaphoresToWaitOn, we will add those
// wait semaphores to the submission of this command buffer.
- void submitCommandBuffer(SyncQueue sync);
+ void submitCommandBuffer(SyncQueue sync, GrGpuFinishedProc finishedProc = nullptr,
+ GrGpuFinishedContext finishedContext = nullptr);
void internalResolveRenderTarget(GrRenderTarget*, bool requiresSubmit);
diff --git a/src/gpu/vk/GrVkResourceProvider.cpp b/src/gpu/vk/GrVkResourceProvider.cpp
index e232e4e402..c875c71885 100644
--- a/src/gpu/vk/GrVkResourceProvider.cpp
+++ b/src/gpu/vk/GrVkResourceProvider.cpp
@@ -369,6 +369,18 @@ void GrVkResourceProvider::checkCommandBuffers() {
}
}
+void GrVkResourceProvider::addFinishedProcToActiveCommandBuffers(
+ GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext) {
+ sk_sp<GrRefCntedCallback> procRef(new GrRefCntedCallback(finishedProc, finishedContext));
+ for (int i = 0; i < fActiveCommandPools.count(); ++i) {
+ GrVkCommandPool* pool = fActiveCommandPools[i];
+ if (!pool->isOpen()) {
+ GrVkPrimaryCommandBuffer* buffer = pool->getPrimaryCommandBuffer();
+ buffer->addFinishedProc(procRef);
+ }
+ }
+}
+
const GrVkResource* GrVkResourceProvider::findOrCreateStandardUniformBufferResource() {
const GrVkResource* resource = nullptr;
int count = fAvailableUniformBufferResources.count();
diff --git a/src/gpu/vk/GrVkResourceProvider.h b/src/gpu/vk/GrVkResourceProvider.h
index 57481f98f3..3cc35f00d2 100644
--- a/src/gpu/vk/GrVkResourceProvider.h
+++ b/src/gpu/vk/GrVkResourceProvider.h
@@ -92,6 +92,13 @@ public:
void checkCommandBuffers();
+ // We must add the finishedProc to all active command buffers since we may have flushed work
+ // that the client cares about before they explicitly called flush and the GPU may reorder
+ // command execution. So we make sure all previously submitted work finishes before we call the
+ // finishedProc.
+ void addFinishedProcToActiveCommandBuffers(GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext);
+
// Finds or creates a compatible GrVkDescriptorPool for the requested type and count.
// The refcount is incremented and a pointer returned.
// TODO: Currently this will just create a descriptor pool without holding onto a ref itself
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 33f77cfe59..eb64b8cf19 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -670,7 +670,7 @@ sk_sp<SkImage> SkImage::MakeFromAHardwareBufferWithData(GrContext* context,
texContext->writePixels(srcInfo, pixmap.addr(0, 0), pixmap.rowBytes(), 0, 0);
drawingManager->flush(proxy.get(), SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kSyncCpu_FlushFlag, 0, nullptr);
+ kSyncCpu_GrFlushFlag, 0, nullptr, nullptr, nullptr);
return image;
}
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index df694a4c66..4f362055d0 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -244,18 +244,28 @@ void SkSurface::prepareForExternalIO() {
}
void SkSurface::flush() {
- asSB(this)->onFlush(BackendSurfaceAccess::kNoAccess, kNone_FlushFlags, 0, nullptr);
+ asSB(this)->onFlush(BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
+ nullptr, nullptr);
+}
+
+GrSemaphoresSubmitted SkSurface::flush(BackendSurfaceAccess access, GrFlushFlags flags,
+ int numSemaphores, GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
+ return asSB(this)->onFlush(access, flags, numSemaphores, signalSemaphores, finishedProc,
+ finishedContext);
}
GrSemaphoresSubmitted SkSurface::flush(BackendSurfaceAccess access, FlushFlags flags,
int numSemaphores, GrBackendSemaphore signalSemaphores[]) {
- return asSB(this)->onFlush(access, flags, numSemaphores, signalSemaphores);
+ GrFlushFlags grFlags = flags == kSyncCpu_FlushFlag ? kSyncCpu_GrFlushFlag : kNone_GrFlushFlags;
+ return this->flush(access, grFlags, numSemaphores, signalSemaphores);
}
GrSemaphoresSubmitted SkSurface::flushAndSignalSemaphores(int numSemaphores,
GrBackendSemaphore signalSemaphores[]) {
- return asSB(this)->onFlush(BackendSurfaceAccess::kNoAccess, kNone_FlushFlags,
- numSemaphores, signalSemaphores);
+ return asSB(this)->onFlush(BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags,
+ numSemaphores, signalSemaphores, nullptr, nullptr);
}
bool SkSurface::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index f1096df6cb..5b1afccfec 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -80,9 +80,11 @@ 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 GrSemaphoresSubmitted onFlush(BackendSurfaceAccess access, FlushFlags flags,
+ virtual GrSemaphoresSubmitted onFlush(BackendSurfaceAccess access, GrFlushFlags flags,
int numSemaphores,
- GrBackendSemaphore signalSemaphores[]) {
+ GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
return GrSemaphoresSubmitted::kNo;
}
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index aa83d1f89f..5a2a12d485 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -50,8 +50,8 @@ static GrRenderTarget* prepare_rt_for_external_access(SkSurface_Gpu* surface,
}
// Grab the render target *after* firing notifications, as it may get switched if CoW kicks in.
- surface->getDevice()->flushAndSignalSemaphores(SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ surface->getDevice()->flush(SkSurface::BackendSurfaceAccess::kNoAccess,
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
GrRenderTargetContext* rtc = surface->getDevice()->accessRenderTargetContext();
return rtc->accessRenderTarget();
}
@@ -158,10 +158,13 @@ void SkSurface_Gpu::onDiscard() {
fDevice->accessRenderTargetContext()->discard();
}
-GrSemaphoresSubmitted SkSurface_Gpu::onFlush(BackendSurfaceAccess access, FlushFlags flags,
+GrSemaphoresSubmitted SkSurface_Gpu::onFlush(BackendSurfaceAccess access, GrFlushFlags flags,
int numSemaphores,
- GrBackendSemaphore signalSemaphores[]) {
- return fDevice->flushAndSignalSemaphores(access, flags, numSemaphores, signalSemaphores);
+ GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) {
+ return fDevice->flush(access, flags, numSemaphores, signalSemaphores, finishedProc,
+ finishedContext);
}
bool SkSurface_Gpu::onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {
diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h
index 9138d1edc0..eb376c9076 100644
--- a/src/image/SkSurface_Gpu.h
+++ b/src/image/SkSurface_Gpu.h
@@ -32,8 +32,11 @@ public:
void onWritePixels(const SkPixmap&, int x, int y) override;
void onCopyOnWrite(ContentChangeMode) override;
void onDiscard() override;
- GrSemaphoresSubmitted onFlush(BackendSurfaceAccess access, FlushFlags flags, int numSemaphores,
- GrBackendSemaphore signalSemaphores[]) override;
+ GrSemaphoresSubmitted onFlush(BackendSurfaceAccess access, GrFlushFlags flags,
+ int numSemaphores,
+ GrBackendSemaphore signalSemaphores[],
+ GrGpuFinishedProc finishedProc,
+ GrGpuFinishedContext finishedContext) override;
bool onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) override;
bool onCharacterize(SkSurfaceCharacterization*) const override;
bool isCompatible(const SkSurfaceCharacterization&) const;
diff --git a/tests/DefaultPathRendererTest.cpp b/tests/DefaultPathRendererTest.cpp
index 4bc8143cc3..2b685a811e 100644
--- a/tests/DefaultPathRendererTest.cpp
+++ b/tests/DefaultPathRendererTest.cpp
@@ -100,7 +100,7 @@ static void run_test(GrContext* ctx, skiatest::Reporter* reporter) {
SkMatrix::I(), invPath, style);
rtc->prepareForExternalIO(SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
}
{
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 24075584a6..dee270a3d4 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -314,7 +314,7 @@ bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages, int ma
}
// Flush everything, test passes if flush is successful(ie, no asserts are hit, no crashes)
drawingManager->flush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
const GrBackendFormat format =
context->priv().caps()->getBackendFormatFromColorType(kRGBA_8888_SkColorType);
@@ -344,7 +344,7 @@ bool GrDrawingManager::ProgramUnitTest(GrContext* context, int maxStages, int ma
paint.addColorFragmentProcessor(std::move(blockFP));
GrDrawRandomOp(&random, renderTargetContext.get(), std::move(paint));
drawingManager->flush(nullptr, SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
}
}
diff --git a/tests/GrFinishedFlushTest.cpp b/tests/GrFinishedFlushTest.cpp
new file mode 100644
index 0000000000..6b825b14b8
--- /dev/null
+++ b/tests/GrFinishedFlushTest.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Test.h"
+
+#include "GrContext.h"
+#include "GrContextPriv.h"
+#include "GrGpu.h"
+#include "SkSurface.h"
+
+using namespace sk_gpu_test;
+
+static void testing_finished_proc(void* ctx) {
+ int* count = (int*)ctx;
+ *count += 1;
+}
+
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(FlushFinishedProcTest, reporter, ctxInfo) {
+ GrContext* ctx = ctxInfo.grContext();
+
+ SkImageInfo info =
+ SkImageInfo::Make(8, 8, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
+ sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
+ SkCanvas* canvas = surface->getCanvas();
+
+ // We flush the surface first just to get rid of any discards/clears that got recorded from
+ // making the surface.
+ surface->flush();
+ ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
+
+ int count = 0;
+
+ // There is no work on the surface so flushing should immediately call the finished proc.
+ surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
+ testing_finished_proc, (void*)&count);
+
+ REPORTER_ASSERT(reporter, count == 1);
+
+ canvas->clear(SK_ColorRED);
+
+ surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
+ testing_finished_proc, (void*)&count);
+
+ bool isVulkan = ctx->backend() == GrBackendApi::kVulkan;
+ if (isVulkan) {
+ // On Vulkan the command buffer we just submitted may or may not have finished immediately
+ // so the finish proc may not have been called.
+ REPORTER_ASSERT(reporter, count == 1 || count == 2);
+ } else {
+ REPORTER_ASSERT(reporter, count == 2);
+ }
+ ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
+ REPORTER_ASSERT(reporter, count == 2);
+
+ // Test flushing via the GrContext
+ canvas->clear(SK_ColorBLUE);
+ ctx->flush(kNone_GrFlushFlags, 0, nullptr, testing_finished_proc, (void*)&count);
+ if (isVulkan) {
+ // On Vulkan the command buffer we just submitted may or may not have finished immediately
+ // so the finish proc may not have been called.
+ REPORTER_ASSERT(reporter, count == 2 || count == 3);
+ } else {
+ REPORTER_ASSERT(reporter, count == 3);
+ }
+ ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
+ REPORTER_ASSERT(reporter, count == 3);
+
+ // There is no work on the surface so flushing should immediately call the finished proc.
+ ctx->flush(kNone_GrFlushFlags, 0, nullptr, testing_finished_proc, (void*)&count);
+ REPORTER_ASSERT(reporter, count == 4);
+
+ count = 0;
+ int count2 = 0;
+ canvas->clear(SK_ColorGREEN);
+ surface->flush(SkSurface::BackendSurfaceAccess::kNoAccess, kNone_GrFlushFlags, 0, nullptr,
+ testing_finished_proc, (void*)&count);
+ // There is no work to be flushed here so this will return immediately, but make sure the
+ // finished call from this proc isn't called till the previous surface flush also is finished.
+ ctx->flush(kNone_GrFlushFlags, 0, nullptr, testing_finished_proc, (void*)&count2);
+
+ REPORTER_ASSERT(reporter, count == count2);
+
+ ctx->flush(kSyncCpu_GrFlushFlag, 0, nullptr);
+
+ REPORTER_ASSERT(reporter, count == 1);
+ REPORTER_ASSERT(reporter, count == count2);
+}
+
diff --git a/tests/OnFlushCallbackTest.cpp b/tests/OnFlushCallbackTest.cpp
index 758ee7705c..312f38e1ba 100644
--- a/tests/OnFlushCallbackTest.cpp
+++ b/tests/OnFlushCallbackTest.cpp
@@ -583,7 +583,7 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(OnFlushCallbackTest, reporter, ctxInfo) {
}
rtc->prepareForExternalIO(SkSurface::BackendSurfaceAccess::kNoAccess,
- SkSurface::kNone_FlushFlags, 0, nullptr);
+ kNone_GrFlushFlags, 0, nullptr, nullptr, nullptr);
SkBitmap readBack;
readBack.allocN32Pixels(kFinalWidth, kFinalHeight);
diff --git a/tests/SurfaceSemaphoreTest.cpp b/tests/SurfaceSemaphoreTest.cpp
index ccb05ff7b2..fd3b44928e 100644
--- a/tests/SurfaceSemaphoreTest.cpp
+++ b/tests/SurfaceSemaphoreTest.cpp
@@ -144,7 +144,7 @@ void surface_semaphore_test(skiatest::Reporter* reporter,
#endif
if (flushContext) {
- mainCtx->flushAndSignalSemaphores(2, semaphores.get());
+ mainCtx->flush(kNone_GrFlushFlags, 2, semaphores.get());
} else {
mainSurface->flushAndSignalSemaphores(2, semaphores.get());
}
diff --git a/tests/VkHardwareBufferTest.cpp b/tests/VkHardwareBufferTest.cpp
index 4fa4b880e4..920940115f 100644
--- a/tests/VkHardwareBufferTest.cpp
+++ b/tests/VkHardwareBufferTest.cpp
@@ -821,9 +821,9 @@ bool VulkanTestHelper::flushSurfaceAndSignalSemaphore(skiatest::Reporter* report
if (!this->setupSemaphoreForSignaling(reporter, &semaphore)) {
return false;
}
- GrSemaphoresSubmitted submitted = fGrContext->flushAndSignalSemaphores(1, &semaphore);
+ GrSemaphoresSubmitted submitted = fGrContext->flush(kNone_GrFlushFlags, 1, &semaphore);
if (GrSemaphoresSubmitted::kNo == submitted) {
- ERRORF(reporter, "Failing call to flushAndSignalSemaphores on SkSurface");
+ ERRORF(reporter, "Failing call to flush on GrContext");
return false;
}
SkASSERT(semaphore.isInitialized());
diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp
index 7ce6a077f1..fab4ed77c7 100644
--- a/tools/sk_app/VulkanWindowContext.cpp
+++ b/tools/sk_app/VulkanWindowContext.cpp
@@ -508,7 +508,7 @@ void VulkanWindowContext::swapBuffers() {
GrBackendSemaphore beSemaphore;
beSemaphore.initVulkan(backbuffer->fRenderSemaphore);
- surface->flush(SkSurface::BackendSurfaceAccess::kPresent, SkSurface::kNone_FlushFlags,
+ surface->flush(SkSurface::BackendSurfaceAccess::kPresent, kNone_GrFlushFlags,
1, &beSemaphore);
// Submit present operation to present queue