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 GLenum getImplementationColorReadFormat(const gl::Context *context) const override; 62 GLenum getImplementationColorReadType(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 const gl::Framebuffer::DirtyBits &dirtyBits) override; 79 80 angle::Result getSamplePosition(const gl::Context *context, 81 size_t index, 82 GLfloat *xy) const override; 83 84 RenderTargetMtl *getColorReadRenderTarget() const; 85 flipY()86 bool flipY() const { return mFlipY; } 87 88 gl::Rectangle getCompleteRenderArea() const; 89 90 const mtl::RenderPassDesc &getRenderPassDesc(ContextMtl *context); 91 92 // Call this to notify FramebufferMtl whenever its render pass has started. 93 void onStartedDrawingToFrameBuffer(const gl::Context *context); 94 95 // The actual area will be adjusted based on framebuffer flipping property. 96 gl::Rectangle getReadPixelArea(const gl::Rectangle &glArea); 97 98 // NOTE: this method doesn't do the flipping of area. Caller must do it if needed before 99 // callling this. See getReadPixelsArea(). 100 angle::Result readPixelsImpl(const gl::Context *context, 101 const gl::Rectangle &area, 102 const PackPixelsParams &packPixelsParams, 103 RenderTargetMtl *renderTarget, 104 uint8_t *pixels); 105 106 private: 107 void reset(); 108 angle::Result invalidateImpl(ContextMtl *contextMtl, size_t count, const GLenum *attachments); 109 angle::Result clearImpl(const gl::Context *context, 110 gl::DrawBufferMask clearColorBuffers, 111 mtl::ClearRectParams *clearOpts); 112 113 angle::Result clearWithLoadOp(const gl::Context *context, 114 gl::DrawBufferMask clearColorBuffers, 115 const mtl::ClearRectParams &clearOpts); 116 117 angle::Result clearWithDraw(const gl::Context *context, 118 gl::DrawBufferMask clearColorBuffers, 119 const mtl::ClearRectParams &clearOpts); 120 121 angle::Result prepareRenderPass(const gl::Context *context, 122 gl::DrawBufferMask drawColorBuffers, 123 mtl::RenderPassDesc *descOut); 124 125 void overrideClearColor(const mtl::TextureRef &texture, 126 MTLClearColor clearColor, 127 MTLClearColor *colorOut); 128 129 angle::Result updateColorRenderTarget(const gl::Context *context, size_t colorIndexGL); 130 angle::Result updateDepthRenderTarget(const gl::Context *context); 131 angle::Result updateStencilRenderTarget(const gl::Context *context); 132 angle::Result updateCachedRenderTarget(const gl::Context *context, 133 const gl::FramebufferAttachment *attachment, 134 RenderTargetMtl **cachedRenderTarget); 135 136 // NOTE: we cannot use RenderTargetCache here because it doesn't support separate 137 // depth & stencil attachments as of now. Separate depth & stencil could be useful to 138 // save spaces on iOS devices. See doc/PackedDepthStencilSupport.md. 139 std::array<RenderTargetMtl *, mtl::kMaxRenderTargets> mColorRenderTargets; 140 RenderTargetMtl *mDepthRenderTarget = nullptr; 141 RenderTargetMtl *mStencilRenderTarget = nullptr; 142 mtl::RenderPassDesc mRenderPassDesc; 143 const bool mFlipY = false; 144 }; 145 } // namespace rx 146 147 #endif /* LIBANGLE_RENDERER_METAL_FRAMEBUFFERMTL_H */ 148