blob: bdd229f5bd21630900987f79580d361c2f52ef10 [file] [log] [blame]
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// FrameBufferMtl.h:
// Defines the class interface for FrameBufferMtl, implementing FrameBufferImpl.
#import <Metal/Metal.h>
#include "libANGLE/renderer/FramebufferImpl.h"
#include "libANGLE/renderer/metal/RenderTargetMtl.h"
#include "libANGLE/renderer/metal/mtl_render_utils.h"
namespace rx
class ContextMtl;
class SurfaceMtl;
class FramebufferMtl : public FramebufferImpl
explicit FramebufferMtl(const gl::FramebufferState &state,
bool flipY,
bool alwaysDiscardDepthStencil);
~FramebufferMtl() override;
void destroy(const gl::Context *context) override;
angle::Result discard(const gl::Context *context,
size_t count,
const GLenum *attachments) override;
angle::Result invalidate(const gl::Context *context,
size_t count,
const GLenum *attachments) override;
angle::Result invalidateSub(const gl::Context *context,
size_t count,
const GLenum *attachments,
const gl::Rectangle &area) override;
angle::Result clear(const gl::Context *context, GLbitfield mask) override;
angle::Result clearBufferfv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values) override;
angle::Result clearBufferuiv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLuint *values) override;
angle::Result clearBufferiv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLint *values) override;
angle::Result clearBufferfi(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil) override;
GLenum getImplementationColorReadFormat(const gl::Context *context) const override;
GLenum getImplementationColorReadType(const gl::Context *context) const override;
angle::Result readPixels(const gl::Context *context,
const gl::Rectangle &area,
GLenum format,
GLenum type,
void *pixels) override;
angle::Result blit(const gl::Context *context,
const gl::Rectangle &sourceArea,
const gl::Rectangle &destArea,
GLbitfield mask,
GLenum filter) override;
bool checkStatus(const gl::Context *context) const override;
angle::Result syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
angle::Result getSamplePosition(const gl::Context *context,
size_t index,
GLfloat *xy) const override;
RenderTargetMtl *getColorReadRenderTarget() const;
bool flipY() const { return mFlipY; }
gl::Rectangle getCompleteRenderArea() const;
const mtl::RenderPassDesc &getRenderPassDesc(ContextMtl *context);
// Call this to notify FramebufferMtl whenever its render pass has ended.
void onFinishedDrawingToFrameBuffer(const gl::Context *context,
mtl::RenderCommandEncoder *encoder);
// The actual area will be adjusted based on framebuffer flipping property.
gl::Rectangle getReadPixelArea(const gl::Rectangle &glArea);
// NOTE: this method doesn't do the flipping of area. Caller must do it if needed before
// callling this. See getReadPixelsArea().
angle::Result readPixelsImpl(const gl::Context *context,
const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams,
RenderTargetMtl *renderTarget,
uint8_t *pixels);
void reset();
angle::Result invalidateImpl(ContextMtl *contextMtl, size_t count, const GLenum *attachments);
angle::Result clearImpl(const gl::Context *context,
gl::DrawBufferMask clearColorBuffers,
mtl::ClearRectParams *clearOpts);
angle::Result clearWithLoadOp(const gl::Context *context,
gl::DrawBufferMask clearColorBuffers,
const mtl::ClearRectParams &clearOpts);
angle::Result clearWithDraw(const gl::Context *context,
gl::DrawBufferMask clearColorBuffers,
const mtl::ClearRectParams &clearOpts);
angle::Result prepareRenderPass(const gl::Context *context,
gl::DrawBufferMask drawColorBuffers,
mtl::RenderPassDesc *descOut);
void overrideClearColor(const mtl::TextureRef &texture,
MTLClearColor clearColor,
MTLClearColor *colorOut);
angle::Result updateColorRenderTarget(const gl::Context *context, size_t colorIndexGL);
angle::Result updateDepthRenderTarget(const gl::Context *context);
angle::Result updateStencilRenderTarget(const gl::Context *context);
angle::Result updateCachedRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *attachment,
RenderTargetMtl **cachedRenderTarget);
// NOTE: we cannot use RenderTargetCache here because it doesn't support separate
// depth & stencil attachments as of now. Separate depth & stencil could be useful to
// save spaces on iOS devices. See doc/
std::array<RenderTargetMtl *, mtl::kMaxRenderTargets> mColorRenderTargets;
std::array<bool, mtl::kMaxRenderTargets> mDiscardColors;
RenderTargetMtl *mDepthRenderTarget = nullptr;
bool mDiscardDepth = false;
RenderTargetMtl *mStencilRenderTarget = nullptr;
bool mDiscardStencil = false;
mtl::RenderPassDesc mRenderPassDesc;
const bool mAlwaysDiscardDepthStencil;
const bool mFlipY = false;
} // namespace rx