blob: 0d6b277cf0315b31dcd5ed2f2de913d5e1e764e3 [file] [log] [blame]
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef GrMtlRenderTarget_DEFINED
#define GrMtlRenderTarget_DEFINED
#include "src/gpu/ganesh/GrRenderTarget.h"
#include "include/gpu/GrBackendSurface.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/mtl/GrMtlAttachment.h"
#include "src/gpu/ganesh/mtl/GrMtlFramebuffer.h"
#import <Metal/Metal.h>
class GrMtlGpu;
class GrMtlRenderTarget: public GrRenderTarget {
public:
// If sampleCnt is greater than 1 and the texture is single sampled, then a MSAA texture
// is created that will resolve to the wrapped single sample texture.
static sk_sp<GrMtlRenderTarget> MakeWrappedRenderTarget(GrMtlGpu*,
SkISize,
int sampleCnt,
id<MTLTexture>);
~GrMtlRenderTarget() override;
bool canAttemptStencilAttachment(bool useMSAASurface) const override {
SkASSERT(useMSAASurface == (this->numSamples() > 1));
return true;
}
GrMtlAttachment* colorAttachment() const { return fColorAttachment.get(); }
id<MTLTexture> colorMTLTexture() const { return fColorAttachment->mtlTexture(); }
GrMtlAttachment* resolveAttachment() const { return fResolveAttachment.get(); }
id<MTLTexture> resolveMTLTexture() const { return fResolveAttachment->mtlTexture(); }
// Returns the GrMtlAttachment of the non-msaa attachment. If the color attachment has 1 sample,
// then the color attachment will be returned. Otherwise, the resolve attachment is returned.
GrMtlAttachment* nonMSAAAttachment() const {
if (fColorAttachment->numSamples() == 1) {
return fColorAttachment.get();
} else {
return fResolveAttachment.get();
}
}
GrBackendRenderTarget getBackendRenderTarget() const override;
GrBackendFormat backendFormat() const override;
const GrMtlFramebuffer* getFramebuffer(bool withResolve,
bool withStencil);
protected:
GrMtlRenderTarget(GrMtlGpu* gpu,
SkISize,
sk_sp<GrMtlAttachment> colorAttachment,
sk_sp<GrMtlAttachment> resolveAttachment,
std::string_view label);
GrMtlGpu* getMtlGpu() const;
void onAbandon() override;
void onRelease() override;
// This returns zero since the memory should all be handled by the attachments
size_t onGpuMemorySize() const override { return 0; }
void onSetLabel() override;
sk_sp<GrMtlAttachment> fColorAttachment;
sk_sp<GrMtlAttachment> fResolveAttachment;
private:
// Extra param to disambiguate from constructor used by subclasses.
enum Wrapped { kWrapped };
GrMtlRenderTarget(GrMtlGpu* gpu,
SkISize,
sk_sp<GrMtlAttachment> colorAttachment,
sk_sp<GrMtlAttachment> resolveAttachment,
Wrapped,
std::string_view label);
bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override;
// We can have a renderpass with and without resolve attachment or stencil attachment,
// both of these being completely orthogonal. Thus we have a total of 4 types of render passes.
// We then cache a framebuffer for each type of these render passes.
// TODO: add support for other flags if needed
inline static constexpr int kNumCachedFramebuffers = 4;
sk_sp<const GrMtlFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers];
using INHERITED = GrRenderTarget;
};
#endif