Add ability to pre-initialize vulkan semaphores when flushing surfaces

Bug: skia:
Change-Id: I2d3eb68d2ac6045fe3e30350fdd21140e22861d7
Reviewed-on: https://skia-review.googlesource.com/24645
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Greg Daniel 2017-07-20 16:36:01 -04:00 committed by Skia Commit-Bot
parent 807371c15b
commit 8761e0c546
5 changed files with 45 additions and 12 deletions

View File

@ -320,15 +320,21 @@ public:
void flush();
/**
* Issue any pending surface IO to the current backend 3D API. After issuing all commands, we
* will issue numSemaphore semaphores for the gpu to signal. We will then fill in the array
* signalSemaphores with the info on the semaphores we submitted. The client is reposonsible for
* allocating enough space in signalSemaphores to handle numSemaphores of GrBackendSemaphores.
* The client will also take ownership of the returned underlying backend semaphores.
* Issue any pending surface IO to the current backend 3D API. After issuing all commands,
* numSemaphore semaphores will be signaled by the gpu. The client passes in an array of
* numSemaphores GrBackendSemaphores. In general these GrBackendSemaphore's can be either
* initialized or not. If they are initialized, the backend uses the passed in semaphore.
* If it is not initialized, a new semaphore is created and the GrBackendSemaphore object
* is initialized with that semaphore.
*
* If the backend API is OpenGL only uninitialized GrBackendSemaphores are supported.
* If the backend API is Vulkan either initialized or unitialized semaphores are supported.
* If unitialized, the semaphores which are created will be valid for use only with the VkDevice
* with which they were created.
*
* If this call returns false, the GPU backend will not have created or added any semaphores to
* signal. Thus the array of semaphores will remain uninitialized. However, we will still flush
* any pending surface IO.
* signal. Thus the array of semaphores will remain uninitialized. However, any pending surface
* IO will still be flush.
*/
bool flushAndSignalSemaphores(int numSemaphores, GrBackendSemaphore* signalSemaphores);

View File

@ -39,6 +39,8 @@ public:
}
#endif
bool isInitialized() const { return fIsInitialized; }
GrGLsync glSync() const {
if (!fIsInitialized || kOpenGL_GrBackend != fBackend) {
return 0;

View File

@ -1426,7 +1426,12 @@ bool GrRenderTargetContext::prepareForExternalIO(int numSemaphores,
SkTArray<sk_sp<GrSemaphore>> semaphores(numSemaphores);
for (int i = 0; i < numSemaphores; ++i) {
if (backendSemaphores[i].isInitialized()) {
semaphores.push_back(fContext->resourceProvider()->wrapBackendSemaphore(
backendSemaphores[i], kBorrow_GrWrapOwnership));
} else {
semaphores.push_back(fContext->resourceProvider()->makeSemaphore(false));
}
// Create signal semaphore ops and force the final one to call flush.
bool forceFlush = (i == (numSemaphores - 1));
std::unique_ptr<GrOp> signalOp(GrSemaphoreOp::MakeSignal(semaphores.back(),
@ -1438,8 +1443,10 @@ bool GrRenderTargetContext::prepareForExternalIO(int numSemaphores,
this->drawingManager()->prepareSurfaceForExternalIO(fRenderTargetProxy.get());
for (int i = 0; i < numSemaphores; ++i) {
if (!backendSemaphores[i].isInitialized()) {
semaphores[i]->setBackendSemaphore(&backendSemaphores[i]);
}
}
return true;
}

View File

@ -18,7 +18,7 @@
sk_sp<GrVkSemaphore> GrVkSemaphore::Make(const GrVkGpu* gpu, bool isOwned) {
VkSemaphoreCreateInfo createInfo;
memset(&createInfo, 0, sizeof(VkFenceCreateInfo));
memset(&createInfo, 0, sizeof(VkSemaphoreCreateInfo));
createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;

View File

@ -124,6 +124,24 @@ void surface_semaphore_test(skiatest::Reporter* reporter,
mainCanvas->clear(SK_ColorBLUE);
SkAutoTArray<GrBackendSemaphore> semaphores(2);
#ifdef SK_VULKAN
if (kVulkan_GrBackend == mainInfo.backend()) {
// Initialize the secondary semaphore instead of having Ganesh create one internally
GrVkGpu* gpu = static_cast<GrVkGpu*>(mainCtx->getGpu());
const GrVkInterface* interface = gpu->vkInterface();
VkDevice device = gpu->device();
VkSemaphore vkSem;
VkSemaphoreCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
GR_VK_CALL_ERRCHECK(interface, CreateSemaphore(device, &createInfo, nullptr, &vkSem));
semaphores[1].initVulkan(vkSem);
}
#endif
mainSurface->flushAndSignalSemaphores(2, semaphores.get());