blob: 52430a34c3095e01c118ef8e03b04e9207a15737 [file] [log] [blame]
/*
* 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 <Metal/Metal.h>
#include "include/core/SkRefCnt.h"
#include "include/gpu/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<GrMtlCommandBuffer> Make(id<MTLCommandQueue> queue);
~GrMtlCommandBuffer() override;
void releaseResources();
bool commit(bool waitUntilCompleted);
bool hasWork() { return fHasWork; }
void addFinishedCallback(sk_sp<skgpu::RefCntedCallback> callback) {
fFinishedCallbacks.push_back(std::move(callback));
}
id<MTLBlitCommandEncoder> 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<const GrManagedResource>& resource) {
// Disable generic resource tracking for now
// SkASSERT(resource);
// fTrackedResources.push_back(std::move(resource));
}
void addGrBuffer(sk_sp<const GrBuffer> buffer) {
fTrackedGrBuffers.push_back(std::move(buffer));
}
void addGrSurface(sk_sp<const GrSurface> surface) {
fTrackedGrSurfaces.push_back(std::move(surface));
}
void encodeSignalEvent(sk_sp<GrMtlEvent>, uint64_t value);
void encodeWaitForEvent(sk_sp<GrMtlEvent>, 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<MTLCommandBuffer> cmdBuffer)
: fCmdBuffer(cmdBuffer)
, fActiveBlitCommandEncoder(nil)
, fActiveRenderCommandEncoder(nil)
, fPreviousRenderPassDescriptor(nil)
, fHasWork(false) {}
void endAllEncoding();
static const int kInitialTrackedResourcesCount = 32;
skia_private::STArray<
kInitialTrackedResourcesCount, sk_sp<const GrManagedResource>> fTrackedResources;
skia_private::STArray<kInitialTrackedResourcesCount, sk_sp<const GrBuffer>> fTrackedGrBuffers;
skia_private::STArray<16, gr_cb<const GrSurface>> fTrackedGrSurfaces;
id<MTLCommandBuffer> fCmdBuffer;
id<MTLBlitCommandEncoder> fActiveBlitCommandEncoder;
std::unique_ptr<GrMtlRenderCommandEncoder> fActiveRenderCommandEncoder;
MTLRenderPassDescriptor* fPreviousRenderPassDescriptor;
bool fHasWork;
skia_private::TArray<sk_sp<skgpu::RefCntedCallback>> fFinishedCallbacks;
};
GR_NORETAIN_END
#endif