1*c8dee2aaSAndroid Build Coastguard Worker /* 2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2019 Google Inc. 3*c8dee2aaSAndroid Build Coastguard Worker * 4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be 5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file. 6*c8dee2aaSAndroid Build Coastguard Worker */ 7*c8dee2aaSAndroid Build Coastguard Worker 8*c8dee2aaSAndroid Build Coastguard Worker #ifndef GrVkSecondaryCBDrawContext_DEFINED 9*c8dee2aaSAndroid Build Coastguard Worker #define GrVkSecondaryCBDrawContext_DEFINED 10*c8dee2aaSAndroid Build Coastguard Worker 11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h" 12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h" 13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h" 14*c8dee2aaSAndroid Build Coastguard Worker 15*c8dee2aaSAndroid Build Coastguard Worker #include <memory> 16*c8dee2aaSAndroid Build Coastguard Worker 17*c8dee2aaSAndroid Build Coastguard Worker class GrBackendSemaphore; 18*c8dee2aaSAndroid Build Coastguard Worker class GrDeferredDisplayList; 19*c8dee2aaSAndroid Build Coastguard Worker class GrRecordingContext; 20*c8dee2aaSAndroid Build Coastguard Worker class GrSurfaceCharacterization; 21*c8dee2aaSAndroid Build Coastguard Worker struct GrVkDrawableInfo; 22*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::ganesh { 23*c8dee2aaSAndroid Build Coastguard Worker class Device; 24*c8dee2aaSAndroid Build Coastguard Worker } 25*c8dee2aaSAndroid Build Coastguard Worker class SkCanvas; 26*c8dee2aaSAndroid Build Coastguard Worker struct SkImageInfo; 27*c8dee2aaSAndroid Build Coastguard Worker class SkSurfaceProps; 28*c8dee2aaSAndroid Build Coastguard Worker 29*c8dee2aaSAndroid Build Coastguard Worker /** 30*c8dee2aaSAndroid Build Coastguard Worker * This class is a private header that is intended to only be used inside of Chromium. This requires 31*c8dee2aaSAndroid Build Coastguard Worker * Chromium to burrow in and include this specifically since it is not part of skia's public include 32*c8dee2aaSAndroid Build Coastguard Worker * directory. 33*c8dee2aaSAndroid Build Coastguard Worker */ 34*c8dee2aaSAndroid Build Coastguard Worker 35*c8dee2aaSAndroid Build Coastguard Worker /** 36*c8dee2aaSAndroid Build Coastguard Worker * This class is used to draw into an external Vulkan secondary command buffer that is imported 37*c8dee2aaSAndroid Build Coastguard Worker * by the client. The secondary command buffer that gets imported must already have had begin called 38*c8dee2aaSAndroid Build Coastguard Worker * on it with VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT. Thus any draws to the imported 39*c8dee2aaSAndroid Build Coastguard Worker * command buffer cannot require changing the render pass. This requirement means that certain types 40*c8dee2aaSAndroid Build Coastguard Worker * of draws will not be supported when using a GrVkSecondaryCBDrawContext. This includes: 41*c8dee2aaSAndroid Build Coastguard Worker * Draws that require a dst copy for blending will be dropped 42*c8dee2aaSAndroid Build Coastguard Worker * Text draws will be dropped (these may require intermediate uploads of text data) 43*c8dee2aaSAndroid Build Coastguard Worker * Read and Write pixels will not work 44*c8dee2aaSAndroid Build Coastguard Worker * Any other draw that requires a copy will fail (this includes using backdrop filter with save 45*c8dee2aaSAndroid Build Coastguard Worker * layer). 46*c8dee2aaSAndroid Build Coastguard Worker * Stenciling is also disabled, but that should not restrict any actual draws from working. 47*c8dee2aaSAndroid Build Coastguard Worker * 48*c8dee2aaSAndroid Build Coastguard Worker * While using a GrVkSecondaryCBDrawContext, the client can also draw into normal SkSurfaces and 49*c8dee2aaSAndroid Build Coastguard Worker * then draw those SkSufaces (as SkImages) into the GrVkSecondaryCBDrawContext. If any of the 50*c8dee2aaSAndroid Build Coastguard Worker * previously mentioned unsupported draws are needed by the client, they can draw them into an 51*c8dee2aaSAndroid Build Coastguard Worker * offscreen surface, and then draw that into the GrVkSecondaryCBDrawContext. 52*c8dee2aaSAndroid Build Coastguard Worker * 53*c8dee2aaSAndroid Build Coastguard Worker * After all drawing to the GrVkSecondaryCBDrawContext has been done, the client must call flush() 54*c8dee2aaSAndroid Build Coastguard Worker * on the GrVkSecondaryCBDrawContext to actually fill in the secondary VkCommandBuffer with the 55*c8dee2aaSAndroid Build Coastguard Worker * draws. 56*c8dee2aaSAndroid Build Coastguard Worker * 57*c8dee2aaSAndroid Build Coastguard Worker * Additionally, the client must keep the GrVkSecondaryCBDrawContext alive until the secondary 58*c8dee2aaSAndroid Build Coastguard Worker * VkCommandBuffer has been submitted and all work finished on the GPU. Before deleting the 59*c8dee2aaSAndroid Build Coastguard Worker * GrVkSecondaryCBDrawContext, the client must call releaseResources() so that Skia can cleanup 60*c8dee2aaSAndroid Build Coastguard Worker * any internal objects that were created for the draws into the secondary command buffer. 61*c8dee2aaSAndroid Build Coastguard Worker */ 62*c8dee2aaSAndroid Build Coastguard Worker class SK_SPI GrVkSecondaryCBDrawContext : public SkRefCnt { 63*c8dee2aaSAndroid Build Coastguard Worker public: 64*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<GrVkSecondaryCBDrawContext> Make(GrRecordingContext*, 65*c8dee2aaSAndroid Build Coastguard Worker const SkImageInfo&, 66*c8dee2aaSAndroid Build Coastguard Worker const GrVkDrawableInfo&, 67*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps* props); 68*c8dee2aaSAndroid Build Coastguard Worker 69*c8dee2aaSAndroid Build Coastguard Worker ~GrVkSecondaryCBDrawContext() override; 70*c8dee2aaSAndroid Build Coastguard Worker 71*c8dee2aaSAndroid Build Coastguard Worker SkCanvas* getCanvas(); 72*c8dee2aaSAndroid Build Coastguard Worker 73*c8dee2aaSAndroid Build Coastguard Worker // Records all the draws to the imported secondary command buffer and sets any dependent 74*c8dee2aaSAndroid Build Coastguard Worker // offscreen draws to the GPU. 75*c8dee2aaSAndroid Build Coastguard Worker void flush(); 76*c8dee2aaSAndroid Build Coastguard Worker 77*c8dee2aaSAndroid Build Coastguard Worker /** Inserts a list of GPU semaphores that Skia will have the driver wait on before executing 78*c8dee2aaSAndroid Build Coastguard Worker commands for this secondary CB. The wait semaphores will get added to the VkCommandBuffer 79*c8dee2aaSAndroid Build Coastguard Worker owned by this GrContext when flush() is called, and not the command buffer which the 80*c8dee2aaSAndroid Build Coastguard Worker Secondary CB is from. This will guarantee that the driver waits on the semaphores before 81*c8dee2aaSAndroid Build Coastguard Worker the secondary command buffer gets executed. We will submit the semphore to wait at 82*c8dee2aaSAndroid Build Coastguard Worker VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT and VK_PIPELINE_STAGE_TRANSFER_BIT. If this 83*c8dee2aaSAndroid Build Coastguard Worker call returns false, then the GPU back end will not wait on any passed in semaphores, and the 84*c8dee2aaSAndroid Build Coastguard Worker client will still own the semaphores, regardless of the value of deleteSemaphoresAfterWait. 85*c8dee2aaSAndroid Build Coastguard Worker 86*c8dee2aaSAndroid Build Coastguard Worker If deleteSemaphoresAfterWait is false then Skia will not delete the semaphores. In this case 87*c8dee2aaSAndroid Build Coastguard Worker it is the client's responsibility to not destroy or attempt to reuse the semaphores until it 88*c8dee2aaSAndroid Build Coastguard Worker knows that Skia has finished waiting on them. This can be done by using finishedProcs 89*c8dee2aaSAndroid Build Coastguard Worker on flush calls. 90*c8dee2aaSAndroid Build Coastguard Worker 91*c8dee2aaSAndroid Build Coastguard Worker @param numSemaphores size of waitSemaphores array 92*c8dee2aaSAndroid Build Coastguard Worker @param waitSemaphores array of semaphore containers 93*c8dee2aaSAndroid Build Coastguard Worker @paramm deleteSemaphoresAfterWait who owns and should delete the semaphores 94*c8dee2aaSAndroid Build Coastguard Worker @return true if GPU is waiting on semaphores 95*c8dee2aaSAndroid Build Coastguard Worker */ 96*c8dee2aaSAndroid Build Coastguard Worker bool wait(int numSemaphores, 97*c8dee2aaSAndroid Build Coastguard Worker const GrBackendSemaphore waitSemaphores[], 98*c8dee2aaSAndroid Build Coastguard Worker bool deleteSemaphoresAfterWait = true); 99*c8dee2aaSAndroid Build Coastguard Worker 100*c8dee2aaSAndroid Build Coastguard Worker // This call will release all resources held by the draw context. The client must call 101*c8dee2aaSAndroid Build Coastguard Worker // releaseResources() before deleting the drawing context. However, the resources also include 102*c8dee2aaSAndroid Build Coastguard Worker // any Vulkan resources that were created and used for draws. Therefore the client must only 103*c8dee2aaSAndroid Build Coastguard Worker // call releaseResources() after submitting the secondary command buffer, and waiting for it to 104*c8dee2aaSAndroid Build Coastguard Worker // finish on the GPU. If it is called earlier then some vulkan objects may be deleted while they 105*c8dee2aaSAndroid Build Coastguard Worker // are still in use by the GPU. 106*c8dee2aaSAndroid Build Coastguard Worker void releaseResources(); 107*c8dee2aaSAndroid Build Coastguard Worker props()108*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps& props() const { return fProps; } 109*c8dee2aaSAndroid Build Coastguard Worker 110*c8dee2aaSAndroid Build Coastguard Worker // TODO: Fill out these calls to support DDL 111*c8dee2aaSAndroid Build Coastguard Worker bool characterize(GrSurfaceCharacterization* characterization) const; 112*c8dee2aaSAndroid Build Coastguard Worker 113*c8dee2aaSAndroid Build Coastguard Worker #ifndef SK_DDL_IS_UNIQUE_POINTER 114*c8dee2aaSAndroid Build Coastguard Worker bool draw(sk_sp<const GrDeferredDisplayList> deferredDisplayList); 115*c8dee2aaSAndroid Build Coastguard Worker #else 116*c8dee2aaSAndroid Build Coastguard Worker bool draw(const GrDeferredDisplayList* deferredDisplayList); 117*c8dee2aaSAndroid Build Coastguard Worker #endif 118*c8dee2aaSAndroid Build Coastguard Worker 119*c8dee2aaSAndroid Build Coastguard Worker bool isCompatible(const GrSurfaceCharacterization& characterization) const; 120*c8dee2aaSAndroid Build Coastguard Worker 121*c8dee2aaSAndroid Build Coastguard Worker private: 122*c8dee2aaSAndroid Build Coastguard Worker explicit GrVkSecondaryCBDrawContext(sk_sp<skgpu::ganesh::Device>, const SkSurfaceProps*); 123*c8dee2aaSAndroid Build Coastguard Worker 124*c8dee2aaSAndroid Build Coastguard Worker sk_sp<skgpu::ganesh::Device> fDevice; 125*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCanvas> fCachedCanvas; 126*c8dee2aaSAndroid Build Coastguard Worker const SkSurfaceProps fProps; 127*c8dee2aaSAndroid Build Coastguard Worker 128*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = SkRefCnt; 129*c8dee2aaSAndroid Build Coastguard Worker }; 130*c8dee2aaSAndroid Build Coastguard Worker 131*c8dee2aaSAndroid Build Coastguard Worker #endif 132