1 // 2 // Copyright 2019 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 // FrameBufferMtl.h: 7 // Defines the class interface for FrameBufferMtl, implementing FrameBufferImpl. 8 // 9 10 #ifndef LIBANGLE_RENDERER_METAL_FRAMEBUFFERMTL_H_ 11 #define LIBANGLE_RENDERER_METAL_FRAMEBUFFERMTL_H_ 12 13 #import <Metal/Metal.h> 14 15 #include "libANGLE/renderer/FramebufferImpl.h" 16 #include "libANGLE/renderer/metal/RenderTargetMtl.h" 17 #include "libANGLE/renderer/metal/mtl_render_utils.h" 18 19 namespace rx 20 { 21 class ContextMtl; 22 class SurfaceMtl; 23 24 class FramebufferMtl : public FramebufferImpl 25 { 26 public: 27 explicit FramebufferMtl(const gl::FramebufferState &state, bool flipY); 28 ~FramebufferMtl() override; 29 void destroy(const gl::Context *context) override; 30 31 angle::Result discard(const gl::Context *context, 32 size_t count, 33 const GLenum *attachments) override; 34 angle::Result invalidate(const gl::Context *context, 35 size_t count, 36 const GLenum *attachments) override; 37 angle::Result invalidateSub(const gl::Context *context, 38 size_t count, 39 const GLenum *attachments, 40 const gl::Rectangle &area) override; 41 42 angle::Result clear(const gl::Context *context, GLbitfield mask) override; 43 angle::Result clearBufferfv(const gl::Context *context, 44 GLenum buffer, 45 GLint drawbuffer, 46 const GLfloat *values) override; 47 angle::Result clearBufferuiv(const gl::Context *context, 48 GLenum buffer, 49 GLint drawbuffer, 50 const GLuint *values) override; 51 angle::Result clearBufferiv(const gl::Context *context, 52 GLenum buffer, 53 GLint drawbuffer, 54 const GLint *values) override; 55 angle::Result clearBufferfi(const gl::Context *context, 56 GLenum buffer, 57 GLint drawbuffer, 58 GLfloat depth, 59 GLint stencil) override; 60 61 const gl::InternalFormat &getImplementationColorReadFormat( 62 const gl::Context *context) const override; 63 angle::Result readPixels(const gl::Context *context, 64 const gl::Rectangle &area, 65 GLenum format, 66 GLenum type, 67 void *pixels) override; 68 69 angle::Result blit(const gl::Context *context, 70 const gl::Rectangle &sourceArea, 71 const gl::Rectangle &destArea, 72 GLbitfield mask, 73 GLenum filter) override; 74 75 bool checkStatus(const gl::Context *context) const override; 76 77 angle::Result syncState(const gl::Context *context, 78 GLenum binding, 79 const gl::Framebuffer::DirtyBits &dirtyBits) override; 80 81 angle::Result getSamplePosition(const gl::Context *context, 82 size_t index, 83 GLfloat *xy) const override; 84 85 RenderTargetMtl *getColorReadRenderTarget() const; 86 flipY()87 bool flipY() const { return mFlipY; } 88 89 gl::Rectangle getCompleteRenderArea() const; 90 91 const mtl::RenderPassDesc &getRenderPassDesc(ContextMtl *context); 92 93 // Call this to notify FramebufferMtl whenever its render pass has started. 94 void onStartedDrawingToFrameBuffer(const gl::Context *context); 95 96 // The actual area will be adjusted based on framebuffer flipping property. 97 gl::Rectangle getReadPixelArea(const gl::Rectangle &glArea); 98 99 // NOTE: this method doesn't do the flipping of area. Caller must do it if needed before 100 // callling this. See getReadPixelsArea(). 101 angle::Result readPixelsImpl(const gl::Context *context, 102 const gl::Rectangle &area, 103 const PackPixelsParams &packPixelsParams, 104 RenderTargetMtl *renderTarget, 105 uint8_t *pixels); 106 107 private: 108 void reset(); 109 angle::Result invalidateImpl(ContextMtl *contextMtl, size_t count, const GLenum *attachments); 110 angle::Result clearImpl(const gl::Context *context, 111 gl::DrawBufferMask clearColorBuffers, 112 mtl::ClearRectParams *clearOpts); 113 114 angle::Result clearWithLoadOp(const gl::Context *context, 115 gl::DrawBufferMask clearColorBuffers, 116 const mtl::ClearRectParams &clearOpts); 117 118 angle::Result clearWithDraw(const gl::Context *context, 119 gl::DrawBufferMask clearColorBuffers, 120 const mtl::ClearRectParams &clearOpts); 121 122 angle::Result prepareRenderPass(const gl::Context *context, 123 gl::DrawBufferMask drawColorBuffers, 124 mtl::RenderPassDesc *descOut); 125 126 void overrideClearColor(const mtl::TextureRef &texture, 127 MTLClearColor clearColor, 128 MTLClearColor *colorOut); 129 130 angle::Result updateColorRenderTarget(const gl::Context *context, size_t colorIndexGL); 131 angle::Result updateDepthRenderTarget(const gl::Context *context); 132 angle::Result updateStencilRenderTarget(const gl::Context *context); 133 angle::Result updateCachedRenderTarget(const gl::Context *context, 134 const gl::FramebufferAttachment *attachment, 135 RenderTargetMtl **cachedRenderTarget); 136 137 // NOTE: we cannot use RenderTargetCache here because it doesn't support separate 138 // depth & stencil attachments as of now. Separate depth & stencil could be useful to 139 // save spaces on iOS devices. See doc/PackedDepthStencilSupport.md. 140 std::array<RenderTargetMtl *, mtl::kMaxRenderTargets> mColorRenderTargets; 141 RenderTargetMtl *mDepthRenderTarget = nullptr; 142 RenderTargetMtl *mStencilRenderTarget = nullptr; 143 mtl::RenderPassDesc mRenderPassDesc; 144 const bool mFlipY = false; 145 }; 146 } // namespace rx 147 148 #endif /* LIBANGLE_RENDERER_METAL_FRAMEBUFFERMTL_H */ 149