1212#import < QuartzCore/CALayer.h>
1313#import < QuartzCore/CAMetalLayer.h>
1414
15+ #include < unordered_map>
16+
1517#include " libANGLE/renderer/FramebufferImpl.h"
1618#include " libANGLE/renderer/SurfaceImpl.h"
1719#include " libANGLE/renderer/metal/RenderTargetMtl.h"
@@ -29,7 +31,6 @@ class SurfaceMtl : public SurfaceImpl
2931 public:
3032 SurfaceMtl (DisplayMtl *display,
3133 const egl::SurfaceState &state,
32- EGLNativeWindowType window,
3334 const egl::AttributeMap &attribs);
3435 ~SurfaceMtl () override;
3536
@@ -55,19 +56,78 @@ class SurfaceMtl : public SurfaceImpl
5556 egl::Error releaseTexImage (const gl::Context *context, EGLint buffer) override;
5657 egl::Error getSyncValues (EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override;
5758 void setSwapInterval (EGLint interval) override;
58- void setSwapBehavior (EGLint behavior) override;
5959 void setFixedWidth (EGLint width) override;
6060 void setFixedHeight (EGLint height) override;
6161
62- // width and height can change with client window resizing
6362 EGLint getWidth () const override;
6463 EGLint getHeight () const override;
6564
6665 EGLint isPostSubBufferSupported () const override;
6766 EGLint getSwapBehavior () const override;
6867
68+ const mtl::TextureRef &getColorTexture () { return mColorTexture; }
69+ const mtl::Format &getColorFormat () const { return mColorFormat; }
6970 int getSamples () const { return mSamples; }
70- bool preserveBuffer () const { return mRetainBuffer; }
71+
72+ angle::Result getAttachmentRenderTarget (const gl::Context *context,
73+ GLenum binding,
74+ const gl::ImageIndex &imageIndex,
75+ GLsizei samples,
76+ FramebufferAttachmentRenderTarget **rtOut) override;
77+
78+ protected:
79+ // Ensure companion (MS, depth, stencil) textures' size is correct w.r.t color texture.
80+ angle::Result ensureCompanionTexturesSizeCorrect (const gl::Context *context,
81+ const gl::Extents &size);
82+ angle::Result resolveColorTextureIfNeeded (const gl::Context *context);
83+
84+ // Normal textures
85+ mtl::TextureRef mColorTexture;
86+ mtl::TextureRef mDepthTexture;
87+ mtl::TextureRef mStencilTexture;
88+
89+ // Implicit multisample texture
90+ mtl::TextureRef mMSColorTexture;
91+
92+ bool mUsePackedDepthStencil = false ;
93+ bool mAutoResolveMSColorTexture = false ;
94+
95+ mtl::Format mColorFormat;
96+ mtl::Format mDepthFormat;
97+ mtl::Format mStencilFormat;
98+
99+ int mSamples = 0 ;
100+
101+ RenderTargetMtl mColorRenderTarget;
102+ RenderTargetMtl mColorManualResolveRenderTarget;
103+ RenderTargetMtl mDepthRenderTarget;
104+ RenderTargetMtl mStencilRenderTarget;
105+ };
106+
107+ class WindowSurfaceMtl : public SurfaceMtl
108+ {
109+ public:
110+ WindowSurfaceMtl (DisplayMtl *display,
111+ const egl::SurfaceState &state,
112+ EGLNativeWindowType window,
113+ const egl::AttributeMap &attribs);
114+ ~WindowSurfaceMtl () override;
115+
116+ void destroy (const egl::Display *display) override;
117+
118+ egl::Error initialize (const egl::Display *display) override;
119+ FramebufferImpl *createDefaultFramebuffer (const gl::Context *context,
120+ const gl::FramebufferState &state) override;
121+
122+ egl::Error swap (const gl::Context *context) override;
123+
124+ void setSwapInterval (EGLint interval) override;
125+ void setSwapBehavior (EGLint behavior) override;
126+ EGLint getSwapBehavior () const override;
127+
128+ // width and height can change with client window resizing
129+ EGLint getWidth () const override;
130+ EGLint getHeight () const override;
71131
72132 angle::Result getAttachmentRenderTarget (const gl::Context *context,
73133 GLenum binding,
@@ -77,10 +137,12 @@ class SurfaceMtl : public SurfaceImpl
77137
78138 angle::Result ensureCurrentDrawableObtained (const gl::Context *context);
79139
140+ bool preserveBuffer () const { return mRetainBuffer; }
141+
80142 private:
81143 angle::Result swapImpl (const gl::Context *context);
82144 angle::Result obtainNextDrawable (const gl::Context *context);
83- angle::Result ensureTexturesSizeCorrect (const gl::Context *context);
145+ angle::Result ensureCompanionTexturesSizeCorrect (const gl::Context *context);
84146
85147 CGSize calcExpectedDrawableSize () const ;
86148 // Check if metal layer has been resized.
@@ -95,36 +157,64 @@ class SurfaceMtl : public SurfaceImpl
95157 CALayer *mLayer;
96158 mtl::AutoObjCPtr<id <CAMetalDrawable >> mCurrentDrawable = nil ;
97159
160+ // Texture for preserving content of color buffer (used when multisample texture is not
161+ // enabled).
162+ mtl::TextureRef mRetainedColorTexture;
163+
164+ bool mRetainBuffer = false ;
165+
98166 // Cache last known drawable size that is used by GL context. Can be used to detect resize
99167 // event. We don't use mMetalLayer.drawableSize directly since it might be changed internally by
100168 // metal runtime.
101169 CGSize mCurrentKnownDrawableSize;
170+ };
102171
103- // Normal textures
104- mtl::TextureRef mDrawableTexture;
105- mtl::TextureRef mDepthTexture;
106- mtl::TextureRef mStencilTexture;
172+ class OffscreenSurfaceMtl : public SurfaceMtl
173+ {
174+ public:
175+ OffscreenSurfaceMtl (DisplayMtl *display,
176+ const egl::SurfaceState &state,
177+ const egl::AttributeMap &attribs);
178+ ~OffscreenSurfaceMtl () override;
107179
108- // Implicit multisample texture
109- mtl::TextureRef mMSColorTexture;
180+ void destroy (const egl::Display *display) override;
110181
111- // Texture for preserving content of color buffer.
112- mtl::TextureRef mRetainedColorTexture;
182+ egl::Error swap (const gl::Context *context) override;
113183
114- bool mUsePackedDepthStencil = false ;
115- bool mAutoResolveMSColorTexture = false ;
184+ egl::Error bindTexImage (const gl::Context *context,
185+ gl::Texture *texture,
186+ EGLint buffer) override;
187+ egl::Error releaseTexImage (const gl::Context *context, EGLint buffer) override;
116188
117- mtl::Format mColorFormat;
118- mtl::Format mDepthFormat;
119- mtl::Format mStencilFormat;
189+ angle::Result getAttachmentRenderTarget (const gl::Context *context,
190+ GLenum binding,
191+ const gl::ImageIndex &imageIndex,
192+ GLsizei samples,
193+ FramebufferAttachmentRenderTarget **rtOut) override;
120194
121- int mSamples = 0 ;
122- bool mRetainBuffer = false ;
195+ // Get or create implicit MS color texture. Used by glFramebufferTexture2DMultisampleEXT()
196+ // after eglBindTexImage()
197+ angle::Result getAttachmentMSColorTexture (const gl::Context *context,
198+ GLsizei samples,
199+ mtl::TextureRef *texOut);
123200
124- RenderTargetMtl mColorRenderTarget;
125- RenderTargetMtl mColorManualResolveRenderTarget;
126- RenderTargetMtl mDepthRenderTarget;
127- RenderTargetMtl mStencilRenderTarget;
201+ protected:
202+ angle::Result ensureTexturesSizeCorrect (const gl::Context *context);
203+
204+ gl::Extents mSize;
205+
206+ std::unordered_map<GLsizei, mtl::TextureRef> mAttachmentMSColorTextures;
207+ };
208+
209+ class PBufferSurfaceMtl : public OffscreenSurfaceMtl
210+ {
211+ public:
212+ PBufferSurfaceMtl (DisplayMtl *display,
213+ const egl::SurfaceState &state,
214+ const egl::AttributeMap &attribs);
215+
216+ void setFixedWidth (EGLint width) override;
217+ void setFixedHeight (EGLint height) override;
128218};
129219
130220} // namespace rx
0 commit comments