aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-06-16 09:45:32 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-16 14:22:34 +0000
commita5cb781c17c09e01655defd0a84b431996b6a015 (patch)
treed80676c7c69155d0d3eb3cc6e128296b83f8688b /src
parent610842af9eec6b49258311b96485447476305faa (diff)
Revert "Revert "Add API for flushing surfaces with gpu semaphores""
This reverts commit 7292231905c34ed290ba479338f26b56ae2a7792. This change relands the original plus the follow on change: https://skia-review.googlesource.com/20059. Additionally it adds a blacklist for the mac intel bots which don't see to respect the added fences on the GPU. Original change's description: > Revert "Add API for flushing surfaces with gpu semaphores" > > This reverts commit 66366c697853e906d961ae691e2bc5209cdcfa62. > > Reason for revert: Failing test on mac bots > > Original change's description: > > Add API for flushing surfaces with gpu semaphores > > > > BUG=skia: > > > > Change-Id: Ia4bfef784cd5f2516ceccafce958be18a86f91d1 > > Reviewed-on: https://skia-review.googlesource.com/11488 > > Commit-Queue: Greg Daniel <egdaniel@google.com> > > Reviewed-by: Brian Salomon <bsalomon@google.com> > > Reviewed-by: Forrest Reiling <freiling@google.com> > > TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com,brianosman@google.com,freiling@google.com > > Change-Id: I75633a2732d2d48b1926f9ad818a9f1a9196d211 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: skia: > Reviewed-on: https://skia-review.googlesource.com/20063 > Commit-Queue: Greg Daniel <egdaniel@google.com> > Reviewed-by: Greg Daniel <egdaniel@google.com> TBR=egdaniel@google.com,jvanverth@google.com,bsalomon@google.com,brianosman@google.com,freiling@google.com Change-Id: I4dc6c0e1deb0398eeb165a34f0a26af7a58259f1 Reviewed-on: https://skia-review.googlesource.com/20141 Commit-Queue: Greg Daniel <egdaniel@google.com> Reviewed-by: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrGpu.h5
-rw-r--r--src/gpu/GrRenderTargetContext.cpp37
-rw-r--r--src/gpu/GrRenderTargetContext.h9
-rw-r--r--src/gpu/GrResourceProvider.cpp11
-rw-r--r--src/gpu/GrResourceProvider.h8
-rw-r--r--src/gpu/GrSemaphore.h7
-rw-r--r--src/gpu/SkGpuDevice.cpp15
-rw-r--r--src/gpu/SkGpuDevice.h2
-rw-r--r--src/gpu/gl/GrGLCaps.cpp8
-rw-r--r--src/gpu/gl/GrGLGpu.cpp13
-rw-r--r--src/gpu/gl/GrGLGpu.h4
-rw-r--r--src/gpu/gl/GrGLSemaphore.h25
-rw-r--r--src/gpu/ops/GrSemaphoreOp.cpp30
-rw-r--r--src/gpu/ops/GrSemaphoreOp.h14
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.cpp23
-rw-r--r--src/gpu/vk/GrVkCommandBuffer.h2
-rw-r--r--src/gpu/vk/GrVkGpu.cpp40
-rw-r--r--src/gpu/vk/GrVkGpu.h16
-rw-r--r--src/gpu/vk/GrVkSemaphore.cpp30
-rw-r--r--src/gpu/vk/GrVkSemaphore.h15
-rw-r--r--src/image/SkSurface.cpp14
-rw-r--r--src/image/SkSurface_Base.h11
-rw-r--r--src/image/SkSurface_Gpu.cpp8
-rw-r--r--src/image/SkSurface_Gpu.h3
24 files changed, 272 insertions, 78 deletions
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 3c400a8b9c..418b8b418d 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -21,6 +21,7 @@
#include <map>
class GrBackendRenderTarget;
+class GrBackendSemaphore;
class GrBuffer;
class GrContext;
struct GrContextOptions;
@@ -376,7 +377,9 @@ public:
virtual bool waitFence(GrFence, uint64_t timeout = 1000) = 0;
virtual void deleteFence(GrFence) const = 0;
- virtual sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore() = 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;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index c5a115faeb..17a7db8c81 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -9,6 +9,7 @@
#include "../private/GrAuditTrail.h"
#include "../private/SkShadowFlags.h"
#include "GrAppliedClip.h"
+#include "GrBackendSemaphore.h"
#include "GrColor.h"
#include "GrContextPriv.h"
#include "GrDrawingManager.h"
@@ -38,6 +39,7 @@
#include "ops/GrOvalOpFactory.h"
#include "ops/GrRectOpFactory.h"
#include "ops/GrRegionOp.h"
+#include "ops/GrSemaphoreOp.h"
#include "ops/GrShadowRRectOp.h"
#include "ops/GrStencilPathOp.h"
#include "text/GrAtlasTextContext.h"
@@ -508,7 +510,7 @@ void GrRenderTargetContext::drawRect(const GrClip& clip,
const SkStrokeRec& stroke = style->strokeRec();
if (stroke.getStyle() == SkStrokeRec::kFill_Style) {
-
+
if (!fContext->caps()->useDrawInsteadOfClear()) {
// Check if this is a full RT draw and can be replaced with a clear. We don't bother
// checking cases where the RT is fully inside a stroke.
@@ -1429,13 +1431,44 @@ void GrRenderTargetContext::drawImageLattice(const GrClip& clip,
this->addLegacyMeshDrawOp(std::move(pipelineBuilder), clip, std::move(op));
}
-void GrRenderTargetContext::prepareForExternalIO() {
+void GrRenderTargetContext::prepareForExternalIO(int numSemaphores,
+ GrBackendSemaphore* backendSemaphores) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
SkDEBUGCODE(this->validate();)
GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::prepareForExternalIO");
+ SkTArray<sk_sp<GrSemaphore>> semaphores(numSemaphores);
+ for (int i = 0; i < numSemaphores; ++i) {
+ semaphores.push_back(fContext->resourceProvider()->makeSemaphore(false));
+ std::unique_ptr<GrOp> signalOp(GrSemaphoreOp::MakeSignal(semaphores.back(),
+ fRenderTargetProxy.get()));
+ this->getOpList()->addOp(std::move(signalOp), *this->caps());
+ }
+
this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get());
+
+ for (int i = 0; i < numSemaphores; ++i) {
+ semaphores[i]->setBackendSemaphore(&backendSemaphores[i]);
+ }
+}
+
+void GrRenderTargetContext::waitOnSemaphores(int numSemaphores,
+ const GrBackendSemaphore* waitSemaphores) {
+ ASSERT_SINGLE_OWNER
+ RETURN_IF_ABANDONED
+ SkDEBUGCODE(this->validate();)
+ GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::waitOnSemaphores");
+
+ AutoCheckFlush acf(this->drawingManager());
+
+ SkTArray<sk_sp<GrSemaphore>> semaphores(numSemaphores);
+ for (int i = 0; i < numSemaphores; ++i) {
+ sk_sp<GrSemaphore> sema = fContext->resourceProvider()->wrapBackendSemaphore(
+ waitSemaphores[i], kAdopt_GrWrapOwnership);
+ std::unique_ptr<GrOp> waitOp(GrSemaphoreOp::MakeWait(sema, fRenderTargetProxy.get()));
+ this->getOpList()->addOp(std::move(waitOp), *this->caps());
+ }
}
// Can 'path' be drawn as a pair of filled nested rectangles?
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index bc226044dd..a2369dd4fc 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -19,6 +19,7 @@
#include "SkRefCnt.h"
#include "SkSurfaceProps.h"
+class GrBackendSemaphore;
class GrClip;
class GrDrawingManager;
class GrDrawOp;
@@ -302,7 +303,13 @@ 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.
*/
- void prepareForExternalIO();
+ void prepareForExternalIO(int numSemaphores, GrBackendSemaphore* backendSemaphores);
+
+ /**
+ * The next time this GrRenderTargetContext is flushed, the gpu will wait on the passed in
+ * semaphores before executing any commands.
+ */
+ void waitOnSemaphores(int numSemaphores, const GrBackendSemaphore* waitSemaphores);
GrFSAAType fsaaType() const { return fRenderTargetProxy->fsaaType(); }
const GrCaps* caps() const { return fContext->caps(); }
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 52340bb0e9..dccfaae875 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -7,6 +7,7 @@
#include "GrResourceProvider.h"
+#include "GrBackendSemaphore.h"
#include "GrBuffer.h"
#include "GrCaps.h"
#include "GrContext.h"
@@ -505,8 +506,14 @@ sk_sp<GrRenderTarget> GrResourceProvider::wrapBackendTextureAsRenderTarget(
return this->gpu()->wrapBackendTextureAsRenderTarget(tex, origin, sampleCnt);
}
-sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore() {
- return fGpu->makeSemaphore();
+sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
+ return fGpu->makeSemaphore(isOwned);
+}
+
+sk_sp<GrSemaphore> GrResourceProvider::wrapBackendSemaphore(const GrBackendSemaphore& semaphore,
+ GrWrapOwnership ownership) {
+ ASSERT_SINGLE_OWNER
+ return this->isAbandoned() ? nullptr : fGpu->wrapBackendSemaphore(semaphore, ownership);
}
void GrResourceProvider::takeOwnershipOfSemaphore(sk_sp<GrSemaphore> semaphore) {
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 50264ef908..a6ddbc55b0 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -8,13 +8,14 @@
#ifndef GrResourceProvider_DEFINED
#define GrResourceProvider_DEFINED
-#include "GrBackendSurface.h"
#include "GrBuffer.h"
#include "GrPathRange.h"
#include "SkImageInfo.h"
#include "SkScalerContext.h"
class GrBackendRenderTarget;
+class GrBackendSemaphore;
+class GrBackendTexture;
class GrGpu;
class GrPath;
class GrRenderTarget;
@@ -227,7 +228,10 @@ public:
*/
GrGpuResource* findAndRefResourceByUniqueKey(const GrUniqueKey&);
- sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore();
+ sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore(bool isOwned = true);
+
+ sk_sp<GrSemaphore> wrapBackendSemaphore(const GrBackendSemaphore&,
+ GrWrapOwnership = kBorrow_GrWrapOwnership);
// Takes the GrSemaphore and sets the ownership of the semaphore to the GrGpu object used by
// this class. This call is only used when passing a GrSemaphore from one context to another.
diff --git a/src/gpu/GrSemaphore.h b/src/gpu/GrSemaphore.h
index b4843ff780..f6148b015a 100644
--- a/src/gpu/GrSemaphore.h
+++ b/src/gpu/GrSemaphore.h
@@ -10,6 +10,7 @@
#include "SkRefCnt.h"
+class GrBackendSemaphore;
class GrGpu;
class GrSemaphore : public SkRefCnt {
@@ -20,9 +21,15 @@ private:
// GrSemaphore should not be used with its old context.
void resetGpu(const GrGpu* gpu) { fGpu = gpu; }
+ // The derived class will init the GrBackendSemaphore. This is used when flushing with signal
+ // semaphores so we can set the clients GrBackendSemaphore object after we've created the
+ // internal semaphore.
+ virtual void setBackendSemaphore(GrBackendSemaphore*) const = 0;
+
protected:
explicit GrSemaphore(const GrGpu* gpu) : fGpu(gpu) {}
+ friend class GrRenderTargetContext; // setBackendSemaphore
friend class GrResourceProvider; // resetGpu
const GrGpu* fGpu;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index be842baf67..ee6e88d33a 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1730,10 +1730,23 @@ bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
return GrTextUtils::ShouldDisableLCD(paint);
}
+///////////////////////////////////////////////////////////////////////////////
+
void SkGpuDevice::flush() {
+ this->flushAndSignalSemaphores(0, nullptr);
+}
+
+void SkGpuDevice::flushAndSignalSemaphores(int numSemaphores,
+ GrBackendSemaphore* signalSemaphores) {
+ ASSERT_SINGLE_OWNER
+
+ fRenderTargetContext->prepareForExternalIO(numSemaphores, signalSemaphores);
+}
+
+void SkGpuDevice::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {
ASSERT_SINGLE_OWNER
- fRenderTargetContext->prepareForExternalIO();
+ fRenderTargetContext->waitOnSemaphores(numSemaphores, waitSemaphores);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 0b60a96516..317533db82 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -118,6 +118,8 @@ public:
sk_sp<SkSpecialImage> snapSpecial() override;
void flush() override;
+ void flushAndSignalSemaphores(int numSemaphores, GrBackendSemaphore* signalSemaphores);
+ void wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores);
bool onAccessPixels(SkPixmap*) override;
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index d52b73b2e8..95791f12bb 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -599,7 +599,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
}
if (kGL_GrGLStandard == standard) {
- if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
+ if ((version >= GR_GL_VER(4, 0) || ctxInfo.hasExtension("GL_ARB_sample_shading")) &&
ctxInfo.vendor() != kIntel_GrGLVendor) {
fSampleShadingSupport = true;
}
@@ -615,6 +615,12 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
} else if (version >= GR_GL_VER(3, 0)) {
fFenceSyncSupport = true;
}
+#ifdef SK_BUILD_FOR_MAC
+ if (kIntel_GrGLVendor == ctxInfo.vendor()) {
+ // See skia:6770
+ fFenceSyncSupport = false;
+ }
+#endif
// Safely moving textures between contexts requires fences.
fCrossContextTextureSupport = fFenceSyncSupport;
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index b3f8c2caa8..d40160044c 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -9,6 +9,7 @@
#include <cmath>
#include "../private/GrGLSL.h"
+#include "GrBackendSemaphore.h"
#include "GrBackendSurface.h"
#include "GrFixedClip.h"
#include "GrGLBuffer.h"
@@ -4288,10 +4289,16 @@ void GrGLGpu::deleteFence(GrFence fence) const {
this->deleteSync((GrGLsync)fence);
}
-sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrGLGpu::makeSemaphore() {
- return GrGLSemaphore::Make(this);
+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) {
+ return GrGLSemaphore::MakeWrapped(this, semaphore.glSync(), ownership);
+}
+
+
void GrGLGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
GrGLSemaphore* glSem = static_cast<GrGLSemaphore*>(semaphore.get());
@@ -4316,7 +4323,7 @@ void GrGLGpu::deleteSync(GrGLsync sync) const {
sk_sp<GrSemaphore> GrGLGpu::prepareTextureForCrossContextUsage(GrTexture* texture) {
// Set up a semaphore to be signaled once the data is ready, and flush GL
- sk_sp<GrSemaphore> semaphore = this->makeSemaphore();
+ sk_sp<GrSemaphore> semaphore = this->makeSemaphore(true);
this->insertSemaphore(semaphore, true);
return semaphore;
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index f121df3f01..80a12eb7cc 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -166,7 +166,9 @@ public:
bool waitFence(GrFence, uint64_t timeout) override;
void deleteFence(GrFence) const override;
- sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore() 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;
diff --git a/src/gpu/gl/GrGLSemaphore.h b/src/gpu/gl/GrGLSemaphore.h
index f439ebd294..cfc3de9951 100644
--- a/src/gpu/gl/GrGLSemaphore.h
+++ b/src/gpu/gl/GrGLSemaphore.h
@@ -10,16 +10,26 @@
#include "GrSemaphore.h"
-class GrGLGpu;
+#include "GrBackendSemaphore.h"
+#include "GrGLGpu.h"
class GrGLSemaphore : public GrSemaphore {
public:
- static sk_sp<GrGLSemaphore> Make(const GrGLGpu* gpu) {
- return sk_sp<GrGLSemaphore>(new GrGLSemaphore(gpu));
+ static sk_sp<GrGLSemaphore> Make(const GrGLGpu* gpu, bool isOwned) {
+ return sk_sp<GrGLSemaphore>(new GrGLSemaphore(gpu, isOwned));
+ }
+
+ static sk_sp<GrGLSemaphore> MakeWrapped(const GrGLGpu* gpu,
+ GrGLsync sync,
+ GrWrapOwnership ownership) {
+ auto sema = sk_sp<GrGLSemaphore>(new GrGLSemaphore(gpu,
+ kBorrow_GrWrapOwnership != ownership));
+ sema->setSync(sync);
+ return sema;
}
~GrGLSemaphore() override {
- if (fGpu) {
+ if (fIsOwned && fGpu) {
static_cast<const GrGLGpu*>(fGpu)->deleteSync(fSync);
}
}
@@ -28,9 +38,14 @@ public:
void setSync(const GrGLsync& sync) { fSync = sync; }
private:
- GrGLSemaphore(const GrGLGpu* gpu) : INHERITED(gpu), fSync(0) {}
+ GrGLSemaphore(const GrGLGpu* gpu, bool isOwned) : INHERITED(gpu), fSync(0), fIsOwned(isOwned) {}
+
+ void setBackendSemaphore(GrBackendSemaphore* backendSemaphore) const override {
+ backendSemaphore->initGL(fSync);
+ }
GrGLsync fSync;
+ bool fIsOwned;
typedef GrSemaphore INHERITED;
};
diff --git a/src/gpu/ops/GrSemaphoreOp.cpp b/src/gpu/ops/GrSemaphoreOp.cpp
index e83096d52a..f50d9c056d 100644
--- a/src/gpu/ops/GrSemaphoreOp.cpp
+++ b/src/gpu/ops/GrSemaphoreOp.cpp
@@ -14,15 +14,17 @@ class GrSignalSemaphoreOp final : public GrSemaphoreOp {
public:
DEFINE_OP_CLASS_ID
- static std::unique_ptr<GrSignalSemaphoreOp> Make(sk_sp<GrSemaphore> semaphore) {
- return std::unique_ptr<GrSignalSemaphoreOp>(new GrSignalSemaphoreOp(std::move(semaphore)));
+ static std::unique_ptr<GrSignalSemaphoreOp> Make(sk_sp<GrSemaphore> semaphore,
+ GrRenderTargetProxy* proxy) {
+ return std::unique_ptr<GrSignalSemaphoreOp>(new GrSignalSemaphoreOp(std::move(semaphore),
+ proxy));
}
const char* name() const override { return "SignalSemaphore"; }
private:
- explicit GrSignalSemaphoreOp(sk_sp<GrSemaphore> semaphore)
- : INHERITED(ClassID(), std::move(semaphore)) {}
+ explicit GrSignalSemaphoreOp(sk_sp<GrSemaphore> semaphore, GrRenderTargetProxy* proxy)
+ : INHERITED(ClassID(), std::move(semaphore), proxy) {}
void onExecute(GrOpFlushState* state) override {
state->gpu()->insertSemaphore(fSemaphore);
@@ -35,15 +37,17 @@ class GrWaitSemaphoreOp final : public GrSemaphoreOp {
public:
DEFINE_OP_CLASS_ID
- static std::unique_ptr<GrWaitSemaphoreOp> Make(sk_sp<GrSemaphore> semaphore) {
- return std::unique_ptr<GrWaitSemaphoreOp>(new GrWaitSemaphoreOp(std::move(semaphore)));
+ static std::unique_ptr<GrWaitSemaphoreOp> Make(sk_sp<GrSemaphore> semaphore,
+ GrRenderTargetProxy* proxy) {
+ return std::unique_ptr<GrWaitSemaphoreOp>(new GrWaitSemaphoreOp(std::move(semaphore),
+ proxy));
}
const char* name() const override { return "WaitSemaphore"; }
private:
- explicit GrWaitSemaphoreOp(sk_sp<GrSemaphore> semaphore)
- : INHERITED(ClassID(), std::move(semaphore)) {}
+ explicit GrWaitSemaphoreOp(sk_sp<GrSemaphore> semaphore, GrRenderTargetProxy* proxy)
+ : INHERITED(ClassID(), std::move(semaphore), proxy) {}
void onExecute(GrOpFlushState* state) override {
state->gpu()->waitSemaphore(fSemaphore);
@@ -54,12 +58,14 @@ private:
////////////////////////////////////////////////////////////////////////////////
-std::unique_ptr<GrSemaphoreOp> GrSemaphoreOp::MakeSignal(sk_sp<GrSemaphore> semaphore) {
- return GrSignalSemaphoreOp::Make(std::move(semaphore));
+std::unique_ptr<GrSemaphoreOp> GrSemaphoreOp::MakeSignal(sk_sp<GrSemaphore> semaphore,
+ GrRenderTargetProxy* proxy) {
+ return GrSignalSemaphoreOp::Make(std::move(semaphore), proxy);
}
-std::unique_ptr<GrSemaphoreOp> GrSemaphoreOp::MakeWait(sk_sp<GrSemaphore> semaphore) {
- return GrWaitSemaphoreOp::Make(std::move(semaphore));
+std::unique_ptr<GrSemaphoreOp> GrSemaphoreOp::MakeWait(sk_sp<GrSemaphore> semaphore,
+ GrRenderTargetProxy* proxy) {
+ return GrWaitSemaphoreOp::Make(std::move(semaphore), proxy);
}
diff --git a/src/gpu/ops/GrSemaphoreOp.h b/src/gpu/ops/GrSemaphoreOp.h
index a88b66cfc7..af9566aefd 100644
--- a/src/gpu/ops/GrSemaphoreOp.h
+++ b/src/gpu/ops/GrSemaphoreOp.h
@@ -10,18 +10,24 @@
#include "GrOp.h"
+#include "GrRenderTargetProxy.h"
#include "GrSemaphore.h"
#include "SkRefCnt.h"
class GrSemaphoreOp : public GrOp {
public:
- static std::unique_ptr<GrSemaphoreOp> MakeSignal(sk_sp<GrSemaphore> semaphore);
+ static std::unique_ptr<GrSemaphoreOp> MakeSignal(sk_sp<GrSemaphore> semaphore,
+ GrRenderTargetProxy* proxy);
- static std::unique_ptr<GrSemaphoreOp> MakeWait(sk_sp<GrSemaphore> semaphore);
+ static std::unique_ptr<GrSemaphoreOp> MakeWait(sk_sp<GrSemaphore> semaphore,
+ GrRenderTargetProxy* proxy);
protected:
- GrSemaphoreOp(uint32_t classId, sk_sp<GrSemaphore> semaphore)
- : INHERITED(classId), fSemaphore(std::move(semaphore)) {}
+ GrSemaphoreOp(uint32_t classId, sk_sp<GrSemaphore> semaphore, GrRenderTargetProxy* proxy)
+ : INHERITED(classId), fSemaphore(std::move(semaphore)) {
+ this->setBounds(SkRect::MakeIWH(proxy->width(), proxy->height()),
+ HasAABloat::kNo, IsZeroArea::kNo);
+ }
sk_sp<GrSemaphore> fSemaphore;
diff --git a/src/gpu/vk/GrVkCommandBuffer.cpp b/src/gpu/vk/GrVkCommandBuffer.cpp
index ea0a02cb34..63642d4ed0 100644
--- a/src/gpu/vk/GrVkCommandBuffer.cpp
+++ b/src/gpu/vk/GrVkCommandBuffer.cpp
@@ -402,7 +402,7 @@ void GrVkPrimaryCommandBuffer::submitToQueue(
const GrVkGpu* gpu,
VkQueue queue,
GrVkGpu::SyncQueue sync,
- const GrVkSemaphore::Resource* signalSemaphore,
+ SkTArray<const GrVkSemaphore::Resource*>& signalSemaphores,
SkTArray<const GrVkSemaphore::Resource*>& waitSemaphores) {
SkASSERT(!fIsActive);
@@ -418,23 +418,20 @@ void GrVkPrimaryCommandBuffer::submitToQueue(
GR_VK_CALL(gpu->vkInterface(), ResetFences(gpu->device(), 1, &fSubmitFence));
}
- if (signalSemaphore) {
- this->addResource(signalSemaphore);
+ int signalCount = signalSemaphores.count();
+ SkTArray<VkSemaphore> vkSignalSem(signalCount);
+ for (int i = 0; i < signalCount; ++i) {
+ this->addResource(signalSemaphores[i]);
+ vkSignalSem.push_back(signalSemaphores[i]->semaphore());
}
int waitCount = waitSemaphores.count();
SkTArray<VkSemaphore> vkWaitSems(waitCount);
SkTArray<VkPipelineStageFlags> vkWaitStages(waitCount);
- if (waitCount) {
- for (int i = 0; i < waitCount; ++i) {
- this->addResource(waitSemaphores[i]);
- vkWaitSems.push_back(waitSemaphores[i]->semaphore());
- vkWaitStages.push_back(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
- }
- }
- SkTArray<VkSemaphore> vkSignalSem;
- if (signalSemaphore) {
- vkSignalSem.push_back(signalSemaphore->semaphore());
+ for (int i = 0; i < waitCount; ++i) {
+ this->addResource(waitSemaphores[i]);
+ vkWaitSems.push_back(waitSemaphores[i]->semaphore());
+ vkWaitStages.push_back(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
}
VkSubmitInfo submitInfo;
diff --git a/src/gpu/vk/GrVkCommandBuffer.h b/src/gpu/vk/GrVkCommandBuffer.h
index 1f3c4a50e5..b387885fff 100644
--- a/src/gpu/vk/GrVkCommandBuffer.h
+++ b/src/gpu/vk/GrVkCommandBuffer.h
@@ -298,7 +298,7 @@ public:
const VkImageResolve* regions);
void submitToQueue(const GrVkGpu* gpu, VkQueue queue, GrVkGpu::SyncQueue sync,
- const GrVkSemaphore::Resource* signalSemaphore,
+ SkTArray<const GrVkSemaphore::Resource*>& signalSemaphores,
SkTArray<const GrVkSemaphore::Resource*>& waitSemaphores);
bool finished(const GrVkGpu* gpu) const;
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index f76f06cfc0..b10e9ed59d 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -7,6 +7,7 @@
#include "GrVkGpu.h"
+#include "GrBackendSemaphore.h"
#include "GrBackendSurface.h"
#include "GrContextOptions.h"
#include "GrGeometryProcessor.h"
@@ -191,6 +192,12 @@ void GrVkGpu::destroyResources() {
}
fSemaphoresToWaitOn.reset();
+ for (int i = 0; i < fSemaphoresToSignal.count(); ++i) {
+ fSemaphoresToSignal[i]->unref(this);
+ }
+ fSemaphoresToSignal.reset();
+
+
fCopyManager.destroyResources(this);
// must call this just before we destroy the command pool and VkDevice
@@ -226,12 +233,16 @@ void GrVkGpu::disconnect(DisconnectType type) {
for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) {
fSemaphoresToWaitOn[i]->unrefAndAbandon();
}
+ for (int i = 0; i < fSemaphoresToSignal.count(); ++i) {
+ fSemaphoresToSignal[i]->unrefAndAbandon();
+ }
fCopyManager.abandonResources();
// must call this just before we destroy the command pool and VkDevice
fResourceProvider.abandonResources();
}
fSemaphoresToWaitOn.reset();
+ fSemaphoresToSignal.reset();
#ifdef SK_ENABLE_VK_LAYERS
fCallback = VK_NULL_HANDLE;
#endif
@@ -249,17 +260,20 @@ GrGpuCommandBuffer* GrVkGpu::createCommandBuffer(
return new GrVkGpuCommandBuffer(this, colorInfo, stencilInfo);
}
-void GrVkGpu::submitCommandBuffer(SyncQueue sync,
- const GrVkSemaphore::Resource* signalSemaphore) {
+void GrVkGpu::submitCommandBuffer(SyncQueue sync) {
SkASSERT(fCurrentCmdBuffer);
fCurrentCmdBuffer->end(this);
- fCurrentCmdBuffer->submitToQueue(this, fQueue, sync, signalSemaphore, fSemaphoresToWaitOn);
+ fCurrentCmdBuffer->submitToQueue(this, fQueue, sync, fSemaphoresToSignal, fSemaphoresToWaitOn);
for (int i = 0; i < fSemaphoresToWaitOn.count(); ++i) {
fSemaphoresToWaitOn[i]->unref(this);
}
fSemaphoresToWaitOn.reset();
+ for (int i = 0; i < fSemaphoresToSignal.count(); ++i) {
+ fSemaphoresToSignal[i]->unref(this);
+ }
+ fSemaphoresToSignal.reset();
fResourceProvider.checkCommandBuffers();
@@ -1937,15 +1951,25 @@ void GrVkGpu::deleteFence(GrFence fence) const {
VK_CALL(DestroyFence(this->device(), (VkFence)fence, nullptr));
}
-sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrVkGpu::makeSemaphore() {
- return GrVkSemaphore::Make(this);
+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) {
+ return GrVkSemaphore::MakeWrapped(this, semaphore.vkSemaphore(), ownership);
}
-void GrVkGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool /*flush*/) {
+void GrVkGpu::insertSemaphore(sk_sp<GrSemaphore> semaphore, bool flush) {
GrVkSemaphore* vkSem = static_cast<GrVkSemaphore*>(semaphore.get());
- // We *always* flush, so ignore that parameter
- this->submitCommandBuffer(kSkip_SyncQueue, vkSem->getResource());
+ 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) {
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index f81daea336..236b34a3c1 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -131,7 +131,9 @@ public:
bool waitFence(GrFence, uint64_t timeout) override;
void deleteFence(GrFence) const override;
- sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT makeSemaphore() 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;
@@ -208,12 +210,11 @@ private:
// 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 the signalSemaphore is not VK_NULL_HANDLE,
- // we will signal the semaphore at the end of this command buffer. If this GrVkGpu object has
- // any semaphores in fSemaphoresToWaitOn, we will add those wait semaphores to this command
- // buffer when submitting.
- void submitCommandBuffer(SyncQueue sync,
- const GrVkSemaphore::Resource* signalSemaphore = nullptr);
+ // work in the queue to finish before returning. If this GrVkGpu object has any semaphores in
+ // 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 internalResolveRenderTarget(GrRenderTarget* target, bool requiresSubmit);
@@ -267,6 +268,7 @@ private:
GrVkPrimaryCommandBuffer* fCurrentCmdBuffer;
SkSTArray<1, const GrVkSemaphore::Resource*> fSemaphoresToWaitOn;
+ SkSTArray<1, const GrVkSemaphore::Resource*> fSemaphoresToSignal;
VkPhysicalDeviceMemoryProperties fPhysDevMemProps;
diff --git a/src/gpu/vk/GrVkSemaphore.cpp b/src/gpu/vk/GrVkSemaphore.cpp
index d84635f85e..d201458b27 100644
--- a/src/gpu/vk/GrVkSemaphore.cpp
+++ b/src/gpu/vk/GrVkSemaphore.cpp
@@ -7,6 +7,7 @@
#include "GrVkSemaphore.h"
+#include "GrBackendSemaphore.h"
#include "GrVkGpu.h"
#include "GrVkUtil.h"
@@ -15,7 +16,7 @@
#undef CreateSemaphore
#endif
-sk_sp<GrVkSemaphore> GrVkSemaphore::Make(const GrVkGpu* gpu) {
+sk_sp<GrVkSemaphore> GrVkSemaphore::Make(const GrVkGpu* gpu, bool isOwned) {
VkSemaphoreCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkFenceCreateInfo));
createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@@ -25,11 +26,22 @@ sk_sp<GrVkSemaphore> GrVkSemaphore::Make(const GrVkGpu* gpu) {
GR_VK_CALL_ERRCHECK(gpu->vkInterface(),
CreateSemaphore(gpu->device(), &createInfo, nullptr, &semaphore));
- return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore));
+ return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore, isOwned));
}
-GrVkSemaphore::GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore) : INHERITED(gpu) {
- fResource = new Resource(semaphore);
+sk_sp<GrVkSemaphore> GrVkSemaphore::MakeWrapped(const GrVkGpu* gpu,
+ VkSemaphore semaphore,
+ GrWrapOwnership ownership) {
+ if (VK_NULL_HANDLE == semaphore) {
+ return nullptr;
+ }
+ return sk_sp<GrVkSemaphore>(new GrVkSemaphore(gpu, semaphore,
+ kBorrow_GrWrapOwnership != ownership));
+}
+
+GrVkSemaphore::GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool isOwned)
+ : INHERITED(gpu) {
+ fResource = new Resource(semaphore, isOwned);
}
GrVkSemaphore::~GrVkSemaphore() {
@@ -41,7 +53,13 @@ GrVkSemaphore::~GrVkSemaphore() {
}
void GrVkSemaphore::Resource::freeGPUData(const GrVkGpu* gpu) const {
- GR_VK_CALL(gpu->vkInterface(),
- DestroySemaphore(gpu->device(), fSemaphore, nullptr));
+ if (fIsOwned) {
+ GR_VK_CALL(gpu->vkInterface(),
+ DestroySemaphore(gpu->device(), fSemaphore, nullptr));
+ }
+}
+
+void GrVkSemaphore::setBackendSemaphore(GrBackendSemaphore* backendSemaphore) const {
+ backendSemaphore->initVulkan(fResource->semaphore());
}
diff --git a/src/gpu/vk/GrVkSemaphore.h b/src/gpu/vk/GrVkSemaphore.h
index 0a3bc1742b..b99eb944f7 100644
--- a/src/gpu/vk/GrVkSemaphore.h
+++ b/src/gpu/vk/GrVkSemaphore.h
@@ -13,17 +13,23 @@
#include "vk/GrVkTypes.h"
+class GrBackendSemaphore;
class GrVkGpu;
class GrVkSemaphore : public GrSemaphore {
public:
- static sk_sp<GrVkSemaphore> Make(const GrVkGpu* gpu);
+ static sk_sp<GrVkSemaphore> Make(const GrVkGpu* gpu, bool isOwned);
+
+ static sk_sp<GrVkSemaphore> MakeWrapped(const GrVkGpu* gpu,
+ VkSemaphore semaphore,
+ GrWrapOwnership);
~GrVkSemaphore() override;
class Resource : public GrVkResource {
public:
- Resource(VkSemaphore semaphore) : INHERITED(), fSemaphore(semaphore) {}
+ Resource(VkSemaphore semaphore, bool isOwned)
+ : INHERITED(), fSemaphore(semaphore), fIsOwned(isOwned) {}
~Resource() override {}
@@ -38,6 +44,7 @@ public:
void freeGPUData(const GrVkGpu* gpu) const override;
VkSemaphore fSemaphore;
+ bool fIsOwned;
typedef GrVkResource INHERITED;
};
@@ -45,7 +52,9 @@ public:
const Resource* getResource() const { return fResource; }
private:
- GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore);
+ GrVkSemaphore(const GrVkGpu* gpu, VkSemaphore semaphore, bool isOwned);
+
+ void setBackendSemaphore(GrBackendSemaphore*) const override;
const Resource* fResource;
diff --git a/src/image/SkSurface.cpp b/src/image/SkSurface.cpp
index cd2a5f185f..fbd9f836d6 100644
--- a/src/image/SkSurface.cpp
+++ b/src/image/SkSurface.cpp
@@ -184,7 +184,19 @@ bool SkSurface::getRenderTargetHandle(GrBackendObject* obj, BackendHandleAccess
}
void SkSurface::prepareForExternalIO() {
- asSB(this)->onPrepareForExternalIO();
+ this->flush();
+}
+
+void SkSurface::flush() {
+ asSB(this)->onFlush(0, nullptr);
+}
+
+void SkSurface::flushAndSignalSemaphores(int numSemaphores, GrBackendSemaphore* signalSemaphores) {
+ return asSB(this)->onFlush(numSemaphores, signalSemaphores);
+}
+
+void SkSurface::wait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {
+ asSB(this)->onWait(numSemaphores, waitSemaphores);
}
//////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/image/SkSurface_Base.h b/src/image/SkSurface_Base.h
index 1b0f9ff975..264a86fc9d 100644
--- a/src/image/SkSurface_Base.h
+++ b/src/image/SkSurface_Base.h
@@ -77,8 +77,17 @@ public:
/**
* Issue any pending surface IO to the current backend 3D API and resolve any surface MSAA.
+ * 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 void onPrepareForExternalIO() {}
+ virtual void onFlush(int numSemaphores, GrBackendSemaphore* signalSemaphores) {}
+
+ /**
+ * Caused the current backend 3D API to wait on the passed in semaphores before executing new
+ * commands on the gpu. Any previously submitting commands will not be blocked by these
+ * semaphores.
+ */
+ virtual void onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {}
inline SkCanvas* getCachedCanvas();
inline sk_sp<SkImage> refCachedImage();
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index d55888767a..0f4b2cb84e 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -166,8 +166,12 @@ void SkSurface_Gpu::onDiscard() {
fDevice->accessRenderTargetContext()->discard();
}
-void SkSurface_Gpu::onPrepareForExternalIO() {
- fDevice->flush();
+void SkSurface_Gpu::onFlush(int numSemaphores, GrBackendSemaphore* signalSemaphores) {
+ fDevice->flushAndSignalSemaphores(numSemaphores, signalSemaphores);
+}
+
+void SkSurface_Gpu::onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) {
+ fDevice->wait(numSemaphores, waitSemaphores);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/image/SkSurface_Gpu.h b/src/image/SkSurface_Gpu.h
index cc8b87dc41..e22ae10bd8 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;
- void onPrepareForExternalIO() override;
+ void onFlush(int numSemaphores, GrBackendSemaphore* signalSemaphores) override;
+ void onWait(int numSemaphores, const GrBackendSemaphore* waitSemaphores) override;
SkGpuDevice* getDevice() { return fDevice.get(); }