/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrMtlCommandBuffer_DEFINED #define GrMtlCommandBuffer_DEFINED #import #include "include/core/SkRefCnt.h" #include "include/gpu/ganesh/GrTypes.h" #include "src/gpu/GpuRefCnt.h" #include "src/gpu/ganesh/GrBuffer.h" #include "src/gpu/ganesh/GrManagedResource.h" #include "src/gpu/ganesh/GrSurface.h" #include "src/gpu/ganesh/mtl/GrMtlRenderCommandEncoder.h" #include "src/gpu/ganesh/mtl/GrMtlUtil.h" class GrMtlEvent; class GrMtlGpu; class GrMtlPipelineState; class GrMtlOpsRenderPass; class GrMtlRenderCommandEncoder; GR_NORETAIN_BEGIN class GrMtlCommandBuffer : public SkRefCnt { public: static sk_sp Make(id queue); ~GrMtlCommandBuffer() override; void releaseResources(); bool commit(bool waitUntilCompleted); bool hasWork() { return fHasWork; } void addFinishedCallback(sk_sp callback) { fFinishedCallbacks.push_back(std::move(callback)); } id getBlitCommandEncoder(); // Tries to reuse current renderCommandEncoder if possible GrMtlRenderCommandEncoder* getRenderCommandEncoder(MTLRenderPassDescriptor*, const GrMtlPipelineState*, GrMtlOpsRenderPass* opsRenderPass); // Replaces current renderCommandEncoder with new one GrMtlRenderCommandEncoder* getRenderCommandEncoder(MTLRenderPassDescriptor*, GrMtlOpsRenderPass*); void addCompletedHandler(MTLCommandBufferHandler block) { [fCmdBuffer addCompletedHandler:block]; } void addResource(const sk_sp& resource) { // Disable generic resource tracking for now // SkASSERT(resource); // fTrackedResources.push_back(std::move(resource)); } void addGrBuffer(sk_sp buffer) { fTrackedGrBuffers.push_back(std::move(buffer)); } void addGrSurface(sk_sp surface) { fTrackedGrSurfaces.push_back(std::move(surface)); } void encodeSignalEvent(sk_sp, uint64_t value); void encodeWaitForEvent(sk_sp, uint64_t value); void waitUntilCompleted() { [fCmdBuffer waitUntilCompleted]; } bool isCompleted() { return fCmdBuffer.status == MTLCommandBufferStatusCompleted || fCmdBuffer.status == MTLCommandBufferStatusError; } void callFinishedCallbacks() { fFinishedCallbacks.clear(); } void pushDebugGroup(NSString* string) { if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { [fCmdBuffer pushDebugGroup:string]; } } void popDebugGroup() { if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) { [fCmdBuffer popDebugGroup]; } } private: GrMtlCommandBuffer(id cmdBuffer) : fCmdBuffer(cmdBuffer) , fActiveBlitCommandEncoder(nil) , fActiveRenderCommandEncoder(nil) , fPreviousRenderPassDescriptor(nil) , fHasWork(false) {} void endAllEncoding(); static const int kInitialTrackedResourcesCount = 32; skia_private::STArray< kInitialTrackedResourcesCount, sk_sp> fTrackedResources; skia_private::STArray> fTrackedGrBuffers; skia_private::STArray<16, gr_cb> fTrackedGrSurfaces; id fCmdBuffer; id fActiveBlitCommandEncoder; std::unique_ptr fActiveRenderCommandEncoder; MTLRenderPassDescriptor* fPreviousRenderPassDescriptor; bool fHasWork; skia_private::TArray> fFinishedCallbacks; }; GR_NORETAIN_END #endif