aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2018-01-09 13:55:33 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-01-09 19:22:27 +0000
commit17b7c054339dfa592571ebd92d2419949baca6f0 (patch)
tree2ecef7a4c9ccfb2edaf72dd5eb56b229ed29a2ca /src/gpu
parente48eb337e1ff16bc0190a0562b01ea4cc9a84ccb (diff)
Update GrSemaphore to allow it to only be used once for signaling and once for waiting.
This is required for Vulkan which doesn't allow a semaphore to be waited on by multiple things at once or signaled from multiple places. Bug: skia: Change-Id: Iac0cb782a6662167c2cab1fd6a2c80378834a480 Reviewed-on: https://skia-review.googlesource.com/92601 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrBackendTextureImageGenerator.cpp3
-rw-r--r--src/gpu/GrGpu.cpp49
-rw-r--r--src/gpu/GrGpu.h14
-rw-r--r--src/gpu/GrRenderTargetContext.cpp3
-rw-r--r--src/gpu/GrResourceProvider.cpp5
-rw-r--r--src/gpu/GrResourceProvider.h6
-rw-r--r--src/gpu/GrSemaphore.h11
-rw-r--r--src/gpu/ddl/GrDDLGpu.h23
-rw-r--r--src/gpu/gl/GrGLGpu.cpp17
-rw-r--r--src/gpu/gl/GrGLGpu.h9
-rw-r--r--src/gpu/mock/GrMockGpu.h9
-rw-r--r--src/gpu/mtl/GrMtlGpu.h9
-rw-r--r--src/gpu/vk/GrVkGpu.cpp17
-rw-r--r--src/gpu/vk/GrVkGpu.h10
14 files changed, 135 insertions, 50 deletions
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 186ca52446..420020b0b6 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -114,7 +114,8 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture(
} else {
// Wait on a semaphore when a new context has just started borrowing the texture. This
// is conservative, but shouldn't be too expensive.
- if (fSemaphore && fLastBorrowingContextID != context->uniqueID()) {
+ if (fSemaphore && !fSemaphore->hasSubmittedWait() &&
+ fLastBorrowingContextID != context->uniqueID()) {
context->getGpu()->waitSemaphore(fSemaphore);
fLastBorrowingContextID = context->uniqueID();
}
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 5b338cdfa0..3a095517b5 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -488,7 +488,8 @@ GrSemaphoresSubmitted GrGpu::finishFlush(int numSemaphores,
sk_sp<GrSemaphore> semaphore;
if (backendSemaphores[i].isInitialized()) {
semaphore = fContext->resourceProvider()->wrapBackendSemaphore(
- backendSemaphores[i], kBorrow_GrWrapOwnership);
+ backendSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillSignal,
+ kBorrow_GrWrapOwnership);
} else {
semaphore = fContext->resourceProvider()->makeSemaphore(false);
}
@@ -513,3 +514,49 @@ void GrGpu::dumpJSON(SkJSONWriter* writer) const {
writer->endObject();
}
+
+void GrGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
+ if (!semaphore) {
+ return;
+ }
+
+ SkASSERT(!semaphore->fSignaled);
+ if (semaphore->fSignaled) {
+ this->onInsertSemaphore(nullptr, flush);
+ return;
+ }
+ this->onInsertSemaphore(semaphore, flush);
+ semaphore->fSignaled = true;
+}
+
+void GrGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
+ if (!semaphore) {
+ return;
+ }
+
+ SkASSERT(!semaphore->fWaitedOn);
+ if (!semaphore->fWaitedOn) {
+ this->onWaitSemaphore(semaphore);
+ semaphore->fWaitedOn = true;
+ }
+}
+
+sk_sp<GrSemaphore> GrGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrResourceProvider::SemaphoreWrapType wrapType,
+ GrWrapOwnership ownership) {
+ sk_sp<GrSemaphore> grSema = this->onWrapBackendSemaphore(semaphore, ownership);
+ if (GrResourceProvider::SemaphoreWrapType::kWillSignal == wrapType) {
+ // This is a safety check to make sure we never try to wait on this semaphore since we
+ // assume the client will wait on it themselves if they've asked us to signal it.
+ grSema->fWaitedOn = true;
+ } else {
+ SkASSERT(GrResourceProvider::SemaphoreWrapType::kWillWait == wrapType);
+ // This is a safety check to make sure we never try to signal this semaphore since we assume
+ // the client will signal it themselves if they've asked us wait on it.
+ grSema->fSignaled = true;
+ }
+
+ SkASSERT(this->caps()->fenceSyncSupport());
+ return grSema;
+}
+
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 3f3610898a..e8e0ab9141 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -377,10 +377,11 @@ public:
virtual void deleteFence(GrFence) const = 0;
virtual sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned = true) = 0;
- virtual sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) = 0;
- virtual void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush = false) = 0;
- virtual void waitSemaphore(sk_sp<GrSemaphore> semaphore) = 0;
+ sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrResourceProvider::SemaphoreWrapType wrapType,
+ GrWrapOwnership ownership);
+ void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush = false);
+ void waitSemaphore(sk_sp<GrSemaphore> semaphore);
/**
* Put this texture in a safe and known state for use across multiple GrContexts. Depending on
@@ -605,6 +606,11 @@ private:
virtual void onFinishFlush(bool insertedSemaphores) = 0;
+ virtual void onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush = false) = 0;
+ virtual void onWaitSemaphore(sk_sp<GrSemaphore> semaphore) = 0;
+ virtual sk_sp<GrSemaphore> onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) = 0;
+
virtual void onDumpJSON(SkJSONWriter*) const {}
void resetContext() {
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index c2b25d8c33..c985e964e8 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1428,7 +1428,8 @@ bool GrRenderTargetContext::waitOnSemaphores(int numSemaphores,
SkTArray<sk_sp<GrSemaphore>> semaphores(numSemaphores);
for (int i = 0; i < numSemaphores; ++i) {
sk_sp<GrSemaphore> sema = fContext->resourceProvider()->wrapBackendSemaphore(
- waitSemaphores[i], kAdopt_GrWrapOwnership);
+ waitSemaphores[i], GrResourceProvider::SemaphoreWrapType::kWillWait,
+ kAdopt_GrWrapOwnership);
std::unique_ptr<GrOp> waitOp(GrSemaphoreOp::MakeWait(sema, fRenderTargetProxy.get()));
this->getRTOpList()->addOp(std::move(waitOp), *this->caps());
}
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 0112b5c15c..048b87fc4e 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -472,9 +472,12 @@ sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool
}
sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ SemaphoreWrapType wrapType,
GrWrapOwnership ownership) {
ASSERT_SINGLE_OWNER
- return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore, ownership);
+ return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore,
+ wrapType,
+ ownership);
}
void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 08da9ae0b0..bf7f28e93d 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -228,7 +228,13 @@ public:
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned = true);
+ enum class SemaphoreWrapType {
+ kWillSignal,
+ kWillWait,
+ };
+
sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&,
+ SemaphoreWrapType wrapType,
GrWrapOwnership = kBorrow_GrWrapOwnership);
// Takes the GrSemaphore and sets the ownership of the semaphore to the GrGpu object used by
diff --git a/src/gpu/GrSemaphore.h b/src/gpu/GrSemaphore.h
index fbc5a6df56..20556d27ac 100644
--- a/src/gpu/GrSemaphore.h
+++ b/src/gpu/GrSemaphore.h
@@ -13,7 +13,15 @@
class GrBackendSemaphore;
class GrGpu;
+/*
+ * Wrapper around a semaphore object which must be implemented on each backend. This semaphores can
+ * at most be signaled once and waited upon once.
+ */
class GrSemaphore : public SkRefCnt {
+public:
+ bool hasSubmittedSignal() const { return fSignaled; }
+ bool hasSubmittedWait() const { return fWaitedOn; }
+
private:
// This function should only be used in the case of exporting and importing a GrSemaphore object
// from one GrContext to another. When exporting, the GrSemaphore should be set to a null GrGpu,
@@ -26,6 +34,9 @@ private:
// internal semaphore.
virtual void setBackendSemaphore(GrBackendSemaphore*) const = 0;
+ bool fSignaled = false;
+ bool fWaitedOn = false;
+
protected:
explicit GrSemaphore(const GrGpu* gpu) : fGpu(gpu) {}
diff --git a/src/gpu/ddl/GrDDLGpu.h b/src/gpu/ddl/GrDDLGpu.h
index aa708bd02b..e97a2abf4a 100644
--- a/src/gpu/ddl/GrDDLGpu.h
+++ b/src/gpu/ddl/GrDDLGpu.h
@@ -72,17 +72,6 @@ public:
SkASSERT(0);
return nullptr;
}
- sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) override {
- SkASSERT(0);
- return nullptr;
- }
- void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {
- SkASSERT(0);
- }
- void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {
- SkASSERT(0);
- }
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override {
SkASSERT(0);
return nullptr;
@@ -158,6 +147,18 @@ private:
void onFinishFlush(bool insertedSemaphores) override { SkASSERT(0); }
+ sk_sp<GrSemaphore> onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) override {
+ SkASSERT(0);
+ return nullptr;
+ }
+ void onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {
+ SkASSERT(0);
+ }
+ void onWaitSemaphore(sk_sp<GrSemaphore> semaphore) override {
+ SkASSERT(0);
+ }
+
GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
int width,
int height) override;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 7b66bcc8a1..fb82a54448 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -4569,26 +4569,29 @@ sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrGLGpu::makeSemaphore(bool isOwned) {
return GrGLSemaphore::Make(this, isOwned);
}
-sk_sp<GrSemaphore> GrGLGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) {
+sk_sp<GrSemaphore> GrGLGpu::onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) {
SkASSERT(this->caps()->fenceSyncSupport());
return GrGLSemaphore::MakeWrapped(this, semaphore.glSync(), ownership);
}
-void GrGLGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
+void GrGLGpu::onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get());
- GrGLsync sync;
- GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
- glSem->setSync(sync);
+ if (glSem) {
+ GrGLsync sync;
+ GL_CALL_RET(sync, FenceSync(GR_GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
+ glSem->setSync(sync);
+ }
if (flush) {
GL_CALL(Flush());
}
}
-void GrGLGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
+void GrGLGpu::onWaitSemaphore(sk_sp<GrSemaphore> semaphore) {
GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get());
+ SkASSERT(glSem);
GL_CALL(WaitSync(glSem->sync(), 0, GR_GL_TIMEOUT_IGNORED));
}
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 4559d38e4a..2087356f04 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -173,10 +173,6 @@ public:
void deleteFence(GrFence) const override;
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
- sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) override;
- void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override;
- void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
@@ -290,6 +286,11 @@ private:
void onFinishFlush(bool insertedSemaphores) override;
+ void onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override;
+ void onWaitSemaphore(sk_sp<GrSemaphore> semaphore) override;
+ sk_sp<GrSemaphore> onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) override;
+
bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
bool copySurfaceAsDraw(GrSurface* dst, GrSurfaceOrigin dstOrigin,
diff --git a/src/gpu/mock/GrMockGpu.h b/src/gpu/mock/GrMockGpu.h
index 4567505546..359782f0c9 100644
--- a/src/gpu/mock/GrMockGpu.h
+++ b/src/gpu/mock/GrMockGpu.h
@@ -58,10 +58,6 @@ public:
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override {
return nullptr;
}
- sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) override { return nullptr; }
- void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {}
- void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {}
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override { return nullptr; }
void submitCommandBuffer(const GrMockGpuRTCommandBuffer*);
@@ -124,6 +120,11 @@ private:
void onFinishFlush(bool insertedSemaphores) override {}
+ sk_sp<GrSemaphore> onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) override { return nullptr; }
+ void onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {}
+ void onWaitSemaphore(sk_sp<GrSemaphore> semaphore) 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 9c5ba8299a..61cbc62f71 100644
--- a/src/gpu/mtl/GrMtlGpu.h
+++ b/src/gpu/mtl/GrMtlGpu.h
@@ -67,10 +67,6 @@ public:
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override {
return nullptr;
}
- sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) override { return nullptr; }
- void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {}
- void waitSemaphore(sk_sp<GrSemaphore> semaphore) override {}
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override { return nullptr; }
private:
@@ -133,6 +129,11 @@ private:
void onFinishFlush(bool insertedSemaphores) override {}
+ sk_sp<GrSemaphore> onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) override { return nullptr; }
+ void onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override {}
+ void onWaitSemaphore(sk_sp<GrSemaphore> semaphore) override {}
+
GrStencilAttachment* createStencilAttachmentForRenderTarget(const GrRenderTarget*,
int width,
int height) override {
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index baf022185f..e1be99e872 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -2162,25 +2162,28 @@ sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrVkGpu::makeSemaphore(bool isOwned) {
return GrVkSemaphore::Make(this, isOwned);
}
-sk_sp<GrSemaphore> GrVkGpu::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) {
+sk_sp<GrSemaphore> GrVkGpu::onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) {
return GrVkSemaphore::MakeWrapped(this, semaphore.vkSemaphore(), ownership);
}
-void GrVkGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
+void GrVkGpu::onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
- const GrVkSemaphore::Resource* resource = vkSem->getResource();
- resource->ref();
- fSemaphoresToSignal.push_back(resource);
+ if (vkSem) {
+ const GrVkSemaphore::Resource* resource = vkSem->getResource();
+ resource->ref();
+ fSemaphoresToSignal.push_back(resource);
+ }
if (flush) {
this->submitCommandBuffer(kSkip_SyncQueue);
}
}
-void GrVkGpu::waitSemaphore(sk_sp<GrSemaphore> semaphore) {
+void GrVkGpu::onWaitSemaphore(sk_sp<GrSemaphore> semaphore) {
GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
+ SkASSERT(vkSem);
const GrVkSemaphore::Resource* resource = vkSem->getResource();
resource->ref();
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index 95d96b1196..e3055945bc 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -135,11 +135,6 @@ public:
void deleteFence(GrFence) const override;
sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned) override;
- sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
- GrWrapOwnership ownership) override;
- void insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override;
- void waitSemaphore(sk_sp<GrSemaphore> semaphore) override;
-
sk_sp<GrSemaphore> prepareTextureForCrossContextUsage(GrTexture*) override;
void generateMipmap(GrVkTexture* tex, GrSurfaceOrigin texOrigin);
@@ -209,6 +204,11 @@ private:
void onFinishFlush(bool insertedSemaphores) override;
+ void onInsertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) override;
+ void onWaitSemaphore(sk_sp<GrSemaphore> semaphore) override;
+ sk_sp<GrSemaphore> onWrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) 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