xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/metal/SurfaceMtl.mm (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker//
2*8975f5c5SAndroid Build Coastguard Worker// Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker// found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker//
6*8975f5c5SAndroid Build Coastguard Worker// SurfaceMtl.mm:
7*8975f5c5SAndroid Build Coastguard Worker//    Implements the class methods for SurfaceMtl.
8*8975f5c5SAndroid Build Coastguard Worker//
9*8975f5c5SAndroid Build Coastguard Worker
10*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/SurfaceMtl.h"
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker#include "common/platform.h"
13*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/Display.h"
14*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/Surface.h"
15*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/ContextMtl.h"
16*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/DisplayMtl.h"
17*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/FrameBufferMtl.h"
18*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/mtl_format_utils.h"
19*8975f5c5SAndroid Build Coastguard Worker#include "libANGLE/renderer/metal/mtl_utils.h"
20*8975f5c5SAndroid Build Coastguard Worker#include "mtl_command_buffer.h"
21*8975f5c5SAndroid Build Coastguard Worker
22*8975f5c5SAndroid Build Coastguard Worker// Compiler can turn on programmatical frame capture in release build by defining
23*8975f5c5SAndroid Build Coastguard Worker// ANGLE_METAL_FRAME_CAPTURE flag.
24*8975f5c5SAndroid Build Coastguard Worker#if defined(NDEBUG) && !defined(ANGLE_METAL_FRAME_CAPTURE)
25*8975f5c5SAndroid Build Coastguard Worker#    define ANGLE_METAL_FRAME_CAPTURE_ENABLED 0
26*8975f5c5SAndroid Build Coastguard Worker#else
27*8975f5c5SAndroid Build Coastguard Worker#    define ANGLE_METAL_FRAME_CAPTURE_ENABLED 1
28*8975f5c5SAndroid Build Coastguard Worker#endif
29*8975f5c5SAndroid Build Coastguard Worker
30*8975f5c5SAndroid Build Coastguard Workernamespace rx
31*8975f5c5SAndroid Build Coastguard Worker{
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Workernamespace
34*8975f5c5SAndroid Build Coastguard Worker{
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Workerconstexpr angle::FormatID kDefaultFrameBufferDepthFormatId   = angle::FormatID::D32_FLOAT;
37*8975f5c5SAndroid Build Coastguard Workerconstexpr angle::FormatID kDefaultFrameBufferStencilFormatId = angle::FormatID::S8_UINT;
38*8975f5c5SAndroid Build Coastguard Workerconstexpr angle::FormatID kDefaultFrameBufferDepthStencilFormatId =
39*8975f5c5SAndroid Build Coastguard Worker    angle::FormatID::D24_UNORM_S8_UINT;
40*8975f5c5SAndroid Build Coastguard Worker
41*8975f5c5SAndroid Build Coastguard Workerangle::Result CreateOrResizeTexture(const gl::Context *context,
42*8975f5c5SAndroid Build Coastguard Worker                                    const mtl::Format &format,
43*8975f5c5SAndroid Build Coastguard Worker                                    uint32_t width,
44*8975f5c5SAndroid Build Coastguard Worker                                    uint32_t height,
45*8975f5c5SAndroid Build Coastguard Worker                                    uint32_t samples,
46*8975f5c5SAndroid Build Coastguard Worker                                    bool renderTargetOnly,
47*8975f5c5SAndroid Build Coastguard Worker                                    mtl::TextureRef *textureOut)
48*8975f5c5SAndroid Build Coastguard Worker{
49*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
50*8975f5c5SAndroid Build Coastguard Worker    bool allowFormatView   = format.hasDepthAndStencilBits();
51*8975f5c5SAndroid Build Coastguard Worker    if (*textureOut)
52*8975f5c5SAndroid Build Coastguard Worker    {
53*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY((*textureOut)->resize(contextMtl, width, height));
54*8975f5c5SAndroid Build Coastguard Worker        size_t resourceSize = EstimateTextureSizeInBytes(format, width, height, 1, samples, 1);
55*8975f5c5SAndroid Build Coastguard Worker        if (*textureOut)
56*8975f5c5SAndroid Build Coastguard Worker        {
57*8975f5c5SAndroid Build Coastguard Worker            (*textureOut)->setEstimatedByteSize(resourceSize);
58*8975f5c5SAndroid Build Coastguard Worker        }
59*8975f5c5SAndroid Build Coastguard Worker    }
60*8975f5c5SAndroid Build Coastguard Worker    else if (samples > 1)
61*8975f5c5SAndroid Build Coastguard Worker    {
62*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(mtl::Texture::Make2DMSTexture(contextMtl, format, width, height, samples,
63*8975f5c5SAndroid Build Coastguard Worker                                                /** renderTargetOnly */ renderTargetOnly,
64*8975f5c5SAndroid Build Coastguard Worker                                                /** allowFormatView */ allowFormatView,
65*8975f5c5SAndroid Build Coastguard Worker                                                textureOut));
66*8975f5c5SAndroid Build Coastguard Worker    }
67*8975f5c5SAndroid Build Coastguard Worker    else
68*8975f5c5SAndroid Build Coastguard Worker    {
69*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(mtl::Texture::Make2DTexture(contextMtl, format, width, height, 1,
70*8975f5c5SAndroid Build Coastguard Worker                                              /** renderTargetOnly */ renderTargetOnly,
71*8975f5c5SAndroid Build Coastguard Worker                                              /** allowFormatView */ allowFormatView, textureOut));
72*8975f5c5SAndroid Build Coastguard Worker    }
73*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
74*8975f5c5SAndroid Build Coastguard Worker}
75*8975f5c5SAndroid Build Coastguard Worker
76*8975f5c5SAndroid Build Coastguard Worker}  // anonymous namespace
77*8975f5c5SAndroid Build Coastguard Worker
78*8975f5c5SAndroid Build Coastguard Worker// SurfaceMtl implementation
79*8975f5c5SAndroid Build Coastguard WorkerSurfaceMtl::SurfaceMtl(DisplayMtl *display,
80*8975f5c5SAndroid Build Coastguard Worker                       const egl::SurfaceState &state,
81*8975f5c5SAndroid Build Coastguard Worker                       const egl::AttributeMap &attribs)
82*8975f5c5SAndroid Build Coastguard Worker    : SurfaceImpl(state)
83*8975f5c5SAndroid Build Coastguard Worker{
84*8975f5c5SAndroid Build Coastguard Worker    mRobustResourceInit =
85*8975f5c5SAndroid Build Coastguard Worker        attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE;
86*8975f5c5SAndroid Build Coastguard Worker    mColorFormat = display->getPixelFormat(angle::FormatID::B8G8R8A8_UNORM);
87*8975f5c5SAndroid Build Coastguard Worker
88*8975f5c5SAndroid Build Coastguard Worker    mSamples = state.config->samples;
89*8975f5c5SAndroid Build Coastguard Worker
90*8975f5c5SAndroid Build Coastguard Worker    int depthBits   = 0;
91*8975f5c5SAndroid Build Coastguard Worker    int stencilBits = 0;
92*8975f5c5SAndroid Build Coastguard Worker    if (state.config)
93*8975f5c5SAndroid Build Coastguard Worker    {
94*8975f5c5SAndroid Build Coastguard Worker        depthBits   = state.config->depthSize;
95*8975f5c5SAndroid Build Coastguard Worker        stencilBits = state.config->stencilSize;
96*8975f5c5SAndroid Build Coastguard Worker    }
97*8975f5c5SAndroid Build Coastguard Worker
98*8975f5c5SAndroid Build Coastguard Worker    if (depthBits && stencilBits)
99*8975f5c5SAndroid Build Coastguard Worker    {
100*8975f5c5SAndroid Build Coastguard Worker        if (display->getFeatures().allowSeparateDepthStencilBuffers.enabled)
101*8975f5c5SAndroid Build Coastguard Worker        {
102*8975f5c5SAndroid Build Coastguard Worker            mDepthFormat   = display->getPixelFormat(kDefaultFrameBufferDepthFormatId);
103*8975f5c5SAndroid Build Coastguard Worker            mStencilFormat = display->getPixelFormat(kDefaultFrameBufferStencilFormatId);
104*8975f5c5SAndroid Build Coastguard Worker        }
105*8975f5c5SAndroid Build Coastguard Worker        else
106*8975f5c5SAndroid Build Coastguard Worker        {
107*8975f5c5SAndroid Build Coastguard Worker            // We must use packed depth stencil
108*8975f5c5SAndroid Build Coastguard Worker            mUsePackedDepthStencil = true;
109*8975f5c5SAndroid Build Coastguard Worker            mDepthFormat   = display->getPixelFormat(kDefaultFrameBufferDepthStencilFormatId);
110*8975f5c5SAndroid Build Coastguard Worker            mStencilFormat = mDepthFormat;
111*8975f5c5SAndroid Build Coastguard Worker        }
112*8975f5c5SAndroid Build Coastguard Worker    }
113*8975f5c5SAndroid Build Coastguard Worker    else if (depthBits)
114*8975f5c5SAndroid Build Coastguard Worker    {
115*8975f5c5SAndroid Build Coastguard Worker        mDepthFormat = display->getPixelFormat(kDefaultFrameBufferDepthFormatId);
116*8975f5c5SAndroid Build Coastguard Worker    }
117*8975f5c5SAndroid Build Coastguard Worker    else if (stencilBits)
118*8975f5c5SAndroid Build Coastguard Worker    {
119*8975f5c5SAndroid Build Coastguard Worker        mStencilFormat = display->getPixelFormat(kDefaultFrameBufferStencilFormatId);
120*8975f5c5SAndroid Build Coastguard Worker    }
121*8975f5c5SAndroid Build Coastguard Worker}
122*8975f5c5SAndroid Build Coastguard Worker
123*8975f5c5SAndroid Build Coastguard WorkerSurfaceMtl::~SurfaceMtl() {}
124*8975f5c5SAndroid Build Coastguard Worker
125*8975f5c5SAndroid Build Coastguard Workervoid SurfaceMtl::destroy(const egl::Display *display)
126*8975f5c5SAndroid Build Coastguard Worker{
127*8975f5c5SAndroid Build Coastguard Worker    mColorTexture   = nullptr;
128*8975f5c5SAndroid Build Coastguard Worker    mDepthTexture   = nullptr;
129*8975f5c5SAndroid Build Coastguard Worker    mStencilTexture = nullptr;
130*8975f5c5SAndroid Build Coastguard Worker
131*8975f5c5SAndroid Build Coastguard Worker    mMSColorTexture = nullptr;
132*8975f5c5SAndroid Build Coastguard Worker
133*8975f5c5SAndroid Build Coastguard Worker    mColorRenderTarget.reset();
134*8975f5c5SAndroid Build Coastguard Worker    mColorManualResolveRenderTarget.reset();
135*8975f5c5SAndroid Build Coastguard Worker    mDepthRenderTarget.reset();
136*8975f5c5SAndroid Build Coastguard Worker    mStencilRenderTarget.reset();
137*8975f5c5SAndroid Build Coastguard Worker}
138*8975f5c5SAndroid Build Coastguard Worker
139*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::initialize(const egl::Display *display)
140*8975f5c5SAndroid Build Coastguard Worker{
141*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
142*8975f5c5SAndroid Build Coastguard Worker}
143*8975f5c5SAndroid Build Coastguard Worker
144*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::makeCurrent(const gl::Context *context)
145*8975f5c5SAndroid Build Coastguard Worker{
146*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
147*8975f5c5SAndroid Build Coastguard Worker    StartFrameCapture(contextMtl);
148*8975f5c5SAndroid Build Coastguard Worker
149*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
150*8975f5c5SAndroid Build Coastguard Worker}
151*8975f5c5SAndroid Build Coastguard Worker
152*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::unMakeCurrent(const gl::Context *context)
153*8975f5c5SAndroid Build Coastguard Worker{
154*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
155*8975f5c5SAndroid Build Coastguard Worker    contextMtl->flushCommandBuffer(mtl::WaitUntilScheduled);
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker    StopFrameCapture();
158*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
159*8975f5c5SAndroid Build Coastguard Worker}
160*8975f5c5SAndroid Build Coastguard Worker
161*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::swap(const gl::Context *context)
162*8975f5c5SAndroid Build Coastguard Worker{
163*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
164*8975f5c5SAndroid Build Coastguard Worker}
165*8975f5c5SAndroid Build Coastguard Worker
166*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::postSubBuffer(const gl::Context *context,
167*8975f5c5SAndroid Build Coastguard Worker                                     EGLint x,
168*8975f5c5SAndroid Build Coastguard Worker                                     EGLint y,
169*8975f5c5SAndroid Build Coastguard Worker                                     EGLint width,
170*8975f5c5SAndroid Build Coastguard Worker                                     EGLint height)
171*8975f5c5SAndroid Build Coastguard Worker{
172*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
173*8975f5c5SAndroid Build Coastguard Worker    return egl::EglBadAccess();
174*8975f5c5SAndroid Build Coastguard Worker}
175*8975f5c5SAndroid Build Coastguard Worker
176*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::querySurfacePointerANGLE(EGLint attribute, void **value)
177*8975f5c5SAndroid Build Coastguard Worker{
178*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
179*8975f5c5SAndroid Build Coastguard Worker    return egl::EglBadAccess();
180*8975f5c5SAndroid Build Coastguard Worker}
181*8975f5c5SAndroid Build Coastguard Worker
182*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::bindTexImage(const gl::Context *context, gl::Texture *texture, EGLint buffer)
183*8975f5c5SAndroid Build Coastguard Worker{
184*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
185*8975f5c5SAndroid Build Coastguard Worker    return egl::EglBadAccess();
186*8975f5c5SAndroid Build Coastguard Worker}
187*8975f5c5SAndroid Build Coastguard Worker
188*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::releaseTexImage(const gl::Context *context, EGLint buffer)
189*8975f5c5SAndroid Build Coastguard Worker{
190*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
191*8975f5c5SAndroid Build Coastguard Worker    return egl::EglBadAccess();
192*8975f5c5SAndroid Build Coastguard Worker}
193*8975f5c5SAndroid Build Coastguard Worker
194*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
195*8975f5c5SAndroid Build Coastguard Worker{
196*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
197*8975f5c5SAndroid Build Coastguard Worker    return egl::EglBadAccess();
198*8975f5c5SAndroid Build Coastguard Worker}
199*8975f5c5SAndroid Build Coastguard Worker
200*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::getMscRate(EGLint *numerator, EGLint *denominator)
201*8975f5c5SAndroid Build Coastguard Worker{
202*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
203*8975f5c5SAndroid Build Coastguard Worker    return egl::EglBadAccess();
204*8975f5c5SAndroid Build Coastguard Worker}
205*8975f5c5SAndroid Build Coastguard Worker
206*8975f5c5SAndroid Build Coastguard Workervoid SurfaceMtl::setSwapInterval(const egl::Display *display, EGLint interval) {}
207*8975f5c5SAndroid Build Coastguard Worker
208*8975f5c5SAndroid Build Coastguard Workervoid SurfaceMtl::setFixedWidth(EGLint width)
209*8975f5c5SAndroid Build Coastguard Worker{
210*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
211*8975f5c5SAndroid Build Coastguard Worker}
212*8975f5c5SAndroid Build Coastguard Worker
213*8975f5c5SAndroid Build Coastguard Workervoid SurfaceMtl::setFixedHeight(EGLint height)
214*8975f5c5SAndroid Build Coastguard Worker{
215*8975f5c5SAndroid Build Coastguard Worker    UNIMPLEMENTED();
216*8975f5c5SAndroid Build Coastguard Worker}
217*8975f5c5SAndroid Build Coastguard Worker
218*8975f5c5SAndroid Build Coastguard WorkerEGLint SurfaceMtl::getWidth() const
219*8975f5c5SAndroid Build Coastguard Worker{
220*8975f5c5SAndroid Build Coastguard Worker    if (mColorTexture)
221*8975f5c5SAndroid Build Coastguard Worker    {
222*8975f5c5SAndroid Build Coastguard Worker        return static_cast<EGLint>(mColorTexture->widthAt0());
223*8975f5c5SAndroid Build Coastguard Worker    }
224*8975f5c5SAndroid Build Coastguard Worker    return 0;
225*8975f5c5SAndroid Build Coastguard Worker}
226*8975f5c5SAndroid Build Coastguard Worker
227*8975f5c5SAndroid Build Coastguard WorkerEGLint SurfaceMtl::getHeight() const
228*8975f5c5SAndroid Build Coastguard Worker{
229*8975f5c5SAndroid Build Coastguard Worker    if (mColorTexture)
230*8975f5c5SAndroid Build Coastguard Worker    {
231*8975f5c5SAndroid Build Coastguard Worker        return static_cast<EGLint>(mColorTexture->heightAt0());
232*8975f5c5SAndroid Build Coastguard Worker    }
233*8975f5c5SAndroid Build Coastguard Worker    return 0;
234*8975f5c5SAndroid Build Coastguard Worker}
235*8975f5c5SAndroid Build Coastguard Worker
236*8975f5c5SAndroid Build Coastguard WorkerEGLint SurfaceMtl::isPostSubBufferSupported() const
237*8975f5c5SAndroid Build Coastguard Worker{
238*8975f5c5SAndroid Build Coastguard Worker    return EGL_FALSE;
239*8975f5c5SAndroid Build Coastguard Worker}
240*8975f5c5SAndroid Build Coastguard Worker
241*8975f5c5SAndroid Build Coastguard WorkerEGLint SurfaceMtl::getSwapBehavior() const
242*8975f5c5SAndroid Build Coastguard Worker{
243*8975f5c5SAndroid Build Coastguard Worker    // dEQP-EGL.functional.query_surface.* requires that for a surface with swap
244*8975f5c5SAndroid Build Coastguard Worker    // behavior=EGL_BUFFER_PRESERVED, config.surfaceType must contain
245*8975f5c5SAndroid Build Coastguard Worker    // EGL_SWAP_BEHAVIOR_PRESERVED_BIT.
246*8975f5c5SAndroid Build Coastguard Worker    // Since we don't support EGL_SWAP_BEHAVIOR_PRESERVED_BIT in egl::Config for now, let's just use
247*8975f5c5SAndroid Build Coastguard Worker    // EGL_BUFFER_DESTROYED as default swap behavior.
248*8975f5c5SAndroid Build Coastguard Worker    return EGL_BUFFER_DESTROYED;
249*8975f5c5SAndroid Build Coastguard Worker}
250*8975f5c5SAndroid Build Coastguard Worker
251*8975f5c5SAndroid Build Coastguard Workerangle::Result SurfaceMtl::initializeContents(const gl::Context *context,
252*8975f5c5SAndroid Build Coastguard Worker                                             GLenum binding,
253*8975f5c5SAndroid Build Coastguard Worker                                             const gl::ImageIndex &imageIndex)
254*8975f5c5SAndroid Build Coastguard Worker{
255*8975f5c5SAndroid Build Coastguard Worker    ASSERT(mColorTexture);
256*8975f5c5SAndroid Build Coastguard Worker
257*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
258*8975f5c5SAndroid Build Coastguard Worker
259*8975f5c5SAndroid Build Coastguard Worker    // Use loadAction=clear
260*8975f5c5SAndroid Build Coastguard Worker    mtl::RenderPassDesc rpDesc;
261*8975f5c5SAndroid Build Coastguard Worker    rpDesc.rasterSampleCount = mColorTexture->samples();
262*8975f5c5SAndroid Build Coastguard Worker
263*8975f5c5SAndroid Build Coastguard Worker    switch (binding)
264*8975f5c5SAndroid Build Coastguard Worker    {
265*8975f5c5SAndroid Build Coastguard Worker        case GL_BACK:
266*8975f5c5SAndroid Build Coastguard Worker        {
267*8975f5c5SAndroid Build Coastguard Worker            if (mColorTextureInitialized)
268*8975f5c5SAndroid Build Coastguard Worker            {
269*8975f5c5SAndroid Build Coastguard Worker                return angle::Result::Continue;
270*8975f5c5SAndroid Build Coastguard Worker            }
271*8975f5c5SAndroid Build Coastguard Worker            rpDesc.numColorAttachments = 1;
272*8975f5c5SAndroid Build Coastguard Worker            mColorRenderTarget.toRenderPassAttachmentDesc(&rpDesc.colorAttachments[0]);
273*8975f5c5SAndroid Build Coastguard Worker            rpDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
274*8975f5c5SAndroid Build Coastguard Worker            MTLClearColor black                   = {};
275*8975f5c5SAndroid Build Coastguard Worker            rpDesc.colorAttachments[0].clearColor =
276*8975f5c5SAndroid Build Coastguard Worker                mtl::EmulatedAlphaClearColor(black, mColorTexture->getColorWritableMask());
277*8975f5c5SAndroid Build Coastguard Worker            mColorTextureInitialized = true;
278*8975f5c5SAndroid Build Coastguard Worker            break;
279*8975f5c5SAndroid Build Coastguard Worker        }
280*8975f5c5SAndroid Build Coastguard Worker        case GL_DEPTH:
281*8975f5c5SAndroid Build Coastguard Worker        case GL_STENCIL:
282*8975f5c5SAndroid Build Coastguard Worker        {
283*8975f5c5SAndroid Build Coastguard Worker            if (mDepthStencilTexturesInitialized)
284*8975f5c5SAndroid Build Coastguard Worker            {
285*8975f5c5SAndroid Build Coastguard Worker                return angle::Result::Continue;
286*8975f5c5SAndroid Build Coastguard Worker            }
287*8975f5c5SAndroid Build Coastguard Worker            if (mDepthTexture)
288*8975f5c5SAndroid Build Coastguard Worker            {
289*8975f5c5SAndroid Build Coastguard Worker                mDepthRenderTarget.toRenderPassAttachmentDesc(&rpDesc.depthAttachment);
290*8975f5c5SAndroid Build Coastguard Worker                rpDesc.depthAttachment.loadAction = MTLLoadActionClear;
291*8975f5c5SAndroid Build Coastguard Worker            }
292*8975f5c5SAndroid Build Coastguard Worker            if (mStencilTexture)
293*8975f5c5SAndroid Build Coastguard Worker            {
294*8975f5c5SAndroid Build Coastguard Worker                mStencilRenderTarget.toRenderPassAttachmentDesc(&rpDesc.stencilAttachment);
295*8975f5c5SAndroid Build Coastguard Worker                rpDesc.stencilAttachment.loadAction = MTLLoadActionClear;
296*8975f5c5SAndroid Build Coastguard Worker            }
297*8975f5c5SAndroid Build Coastguard Worker            mDepthStencilTexturesInitialized = true;
298*8975f5c5SAndroid Build Coastguard Worker            break;
299*8975f5c5SAndroid Build Coastguard Worker        }
300*8975f5c5SAndroid Build Coastguard Worker        default:
301*8975f5c5SAndroid Build Coastguard Worker            UNREACHABLE();
302*8975f5c5SAndroid Build Coastguard Worker            break;
303*8975f5c5SAndroid Build Coastguard Worker    }
304*8975f5c5SAndroid Build Coastguard Worker    mtl::RenderCommandEncoder *encoder = contextMtl->getRenderPassCommandEncoder(rpDesc);
305*8975f5c5SAndroid Build Coastguard Worker    encoder->setStoreAction(MTLStoreActionStore);
306*8975f5c5SAndroid Build Coastguard Worker
307*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
308*8975f5c5SAndroid Build Coastguard Worker}
309*8975f5c5SAndroid Build Coastguard Worker
310*8975f5c5SAndroid Build Coastguard Workerangle::Result SurfaceMtl::getAttachmentRenderTarget(const gl::Context *context,
311*8975f5c5SAndroid Build Coastguard Worker                                                    GLenum binding,
312*8975f5c5SAndroid Build Coastguard Worker                                                    const gl::ImageIndex &imageIndex,
313*8975f5c5SAndroid Build Coastguard Worker                                                    GLsizei samples,
314*8975f5c5SAndroid Build Coastguard Worker                                                    FramebufferAttachmentRenderTarget **rtOut)
315*8975f5c5SAndroid Build Coastguard Worker{
316*8975f5c5SAndroid Build Coastguard Worker    ASSERT(mColorTexture);
317*8975f5c5SAndroid Build Coastguard Worker
318*8975f5c5SAndroid Build Coastguard Worker    switch (binding)
319*8975f5c5SAndroid Build Coastguard Worker    {
320*8975f5c5SAndroid Build Coastguard Worker        case GL_BACK:
321*8975f5c5SAndroid Build Coastguard Worker            *rtOut = &mColorRenderTarget;
322*8975f5c5SAndroid Build Coastguard Worker            break;
323*8975f5c5SAndroid Build Coastguard Worker        case GL_DEPTH:
324*8975f5c5SAndroid Build Coastguard Worker            *rtOut = mDepthFormat.valid() ? &mDepthRenderTarget : nullptr;
325*8975f5c5SAndroid Build Coastguard Worker            break;
326*8975f5c5SAndroid Build Coastguard Worker        case GL_STENCIL:
327*8975f5c5SAndroid Build Coastguard Worker            *rtOut = mStencilFormat.valid() ? &mStencilRenderTarget : nullptr;
328*8975f5c5SAndroid Build Coastguard Worker            break;
329*8975f5c5SAndroid Build Coastguard Worker        case GL_DEPTH_STENCIL:
330*8975f5c5SAndroid Build Coastguard Worker            // NOTE(hqle): ES 3.0 feature
331*8975f5c5SAndroid Build Coastguard Worker            UNREACHABLE();
332*8975f5c5SAndroid Build Coastguard Worker            break;
333*8975f5c5SAndroid Build Coastguard Worker    }
334*8975f5c5SAndroid Build Coastguard Worker
335*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
336*8975f5c5SAndroid Build Coastguard Worker}
337*8975f5c5SAndroid Build Coastguard Worker
338*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::attachToFramebuffer(const gl::Context *context, gl::Framebuffer *framebuffer)
339*8975f5c5SAndroid Build Coastguard Worker{
340*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
341*8975f5c5SAndroid Build Coastguard Worker}
342*8975f5c5SAndroid Build Coastguard Worker
343*8975f5c5SAndroid Build Coastguard Workeregl::Error SurfaceMtl::detachFromFramebuffer(const gl::Context *context,
344*8975f5c5SAndroid Build Coastguard Worker                                             gl::Framebuffer *framebuffer)
345*8975f5c5SAndroid Build Coastguard Worker{
346*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
347*8975f5c5SAndroid Build Coastguard Worker}
348*8975f5c5SAndroid Build Coastguard Worker
349*8975f5c5SAndroid Build Coastguard Workerangle::Result SurfaceMtl::ensureCompanionTexturesSizeCorrect(const gl::Context *context,
350*8975f5c5SAndroid Build Coastguard Worker                                                             const gl::Extents &size)
351*8975f5c5SAndroid Build Coastguard Worker{
352*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
353*8975f5c5SAndroid Build Coastguard Worker
354*8975f5c5SAndroid Build Coastguard Worker    ASSERT(mColorTexture);
355*8975f5c5SAndroid Build Coastguard Worker
356*8975f5c5SAndroid Build Coastguard Worker    if (mSamples > 1 && (!mMSColorTexture || mMSColorTexture->sizeAt0() != size))
357*8975f5c5SAndroid Build Coastguard Worker    {
358*8975f5c5SAndroid Build Coastguard Worker        mAutoResolveMSColorTexture =
359*8975f5c5SAndroid Build Coastguard Worker            contextMtl->getDisplay()->getFeatures().allowMultisampleStoreAndResolve.enabled;
360*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(CreateOrResizeTexture(context, mColorFormat, size.width, size.height, mSamples,
361*8975f5c5SAndroid Build Coastguard Worker                                        /** renderTargetOnly */ mAutoResolveMSColorTexture,
362*8975f5c5SAndroid Build Coastguard Worker                                        &mMSColorTexture));
363*8975f5c5SAndroid Build Coastguard Worker
364*8975f5c5SAndroid Build Coastguard Worker        if (mAutoResolveMSColorTexture)
365*8975f5c5SAndroid Build Coastguard Worker        {
366*8975f5c5SAndroid Build Coastguard Worker            // Use auto MSAA resolve at the end of render pass.
367*8975f5c5SAndroid Build Coastguard Worker            mColorRenderTarget.setImplicitMSTexture(mMSColorTexture);
368*8975f5c5SAndroid Build Coastguard Worker        }
369*8975f5c5SAndroid Build Coastguard Worker        else
370*8975f5c5SAndroid Build Coastguard Worker        {
371*8975f5c5SAndroid Build Coastguard Worker            mColorRenderTarget.setTexture(mMSColorTexture);
372*8975f5c5SAndroid Build Coastguard Worker        }
373*8975f5c5SAndroid Build Coastguard Worker    }
374*8975f5c5SAndroid Build Coastguard Worker
375*8975f5c5SAndroid Build Coastguard Worker    if (mDepthFormat.valid() && (!mDepthTexture || mDepthTexture->sizeAt0() != size))
376*8975f5c5SAndroid Build Coastguard Worker    {
377*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(CreateOrResizeTexture(context, mDepthFormat, size.width, size.height, mSamples,
378*8975f5c5SAndroid Build Coastguard Worker                                        /** renderTargetOnly */ false, &mDepthTexture));
379*8975f5c5SAndroid Build Coastguard Worker
380*8975f5c5SAndroid Build Coastguard Worker        mDepthRenderTarget.set(mDepthTexture, mtl::kZeroNativeMipLevel, 0, mDepthFormat);
381*8975f5c5SAndroid Build Coastguard Worker        // Robust resource init: should initialize depth to 1.0.
382*8975f5c5SAndroid Build Coastguard Worker        mDepthStencilTexturesInitialized = false;
383*8975f5c5SAndroid Build Coastguard Worker    }
384*8975f5c5SAndroid Build Coastguard Worker
385*8975f5c5SAndroid Build Coastguard Worker    if (mStencilFormat.valid() && (!mStencilTexture || mStencilTexture->sizeAt0() != size))
386*8975f5c5SAndroid Build Coastguard Worker    {
387*8975f5c5SAndroid Build Coastguard Worker        if (mUsePackedDepthStencil)
388*8975f5c5SAndroid Build Coastguard Worker        {
389*8975f5c5SAndroid Build Coastguard Worker            mStencilTexture = mDepthTexture;
390*8975f5c5SAndroid Build Coastguard Worker        }
391*8975f5c5SAndroid Build Coastguard Worker        else
392*8975f5c5SAndroid Build Coastguard Worker        {
393*8975f5c5SAndroid Build Coastguard Worker            ANGLE_TRY(CreateOrResizeTexture(context, mStencilFormat, size.width, size.height,
394*8975f5c5SAndroid Build Coastguard Worker                                            mSamples,
395*8975f5c5SAndroid Build Coastguard Worker                                            /** renderTargetOnly */ false, &mStencilTexture));
396*8975f5c5SAndroid Build Coastguard Worker        }
397*8975f5c5SAndroid Build Coastguard Worker
398*8975f5c5SAndroid Build Coastguard Worker        mStencilRenderTarget.set(mStencilTexture, mtl::kZeroNativeMipLevel, 0, mStencilFormat);
399*8975f5c5SAndroid Build Coastguard Worker        // Robust resource init: should initialize stencil to zero.
400*8975f5c5SAndroid Build Coastguard Worker        mDepthStencilTexturesInitialized = false;
401*8975f5c5SAndroid Build Coastguard Worker    }
402*8975f5c5SAndroid Build Coastguard Worker
403*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
404*8975f5c5SAndroid Build Coastguard Worker}
405*8975f5c5SAndroid Build Coastguard Worker
406*8975f5c5SAndroid Build Coastguard Workerangle::Result SurfaceMtl::resolveColorTextureIfNeeded(const gl::Context *context)
407*8975f5c5SAndroid Build Coastguard Worker{
408*8975f5c5SAndroid Build Coastguard Worker    ASSERT(mMSColorTexture);
409*8975f5c5SAndroid Build Coastguard Worker    if (!mAutoResolveMSColorTexture)
410*8975f5c5SAndroid Build Coastguard Worker    {
411*8975f5c5SAndroid Build Coastguard Worker        // Manually resolve texture
412*8975f5c5SAndroid Build Coastguard Worker        ContextMtl *contextMtl = mtl::GetImpl(context);
413*8975f5c5SAndroid Build Coastguard Worker
414*8975f5c5SAndroid Build Coastguard Worker        mColorManualResolveRenderTarget.set(mColorTexture, mtl::kZeroNativeMipLevel, 0,
415*8975f5c5SAndroid Build Coastguard Worker                                            mColorFormat);
416*8975f5c5SAndroid Build Coastguard Worker        mtl::RenderCommandEncoder *encoder =
417*8975f5c5SAndroid Build Coastguard Worker            contextMtl->getRenderTargetCommandEncoder(mColorManualResolveRenderTarget);
418*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(contextMtl->getDisplay()->getUtils().blitColorWithDraw(
419*8975f5c5SAndroid Build Coastguard Worker            context, encoder, mColorFormat.actualAngleFormat(), mMSColorTexture));
420*8975f5c5SAndroid Build Coastguard Worker        contextMtl->endEncoding(true);
421*8975f5c5SAndroid Build Coastguard Worker        mColorManualResolveRenderTarget.reset();
422*8975f5c5SAndroid Build Coastguard Worker    }
423*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
424*8975f5c5SAndroid Build Coastguard Worker}
425*8975f5c5SAndroid Build Coastguard Worker
426*8975f5c5SAndroid Build Coastguard Worker// WindowSurfaceMtl implementation.
427*8975f5c5SAndroid Build Coastguard WorkerWindowSurfaceMtl::WindowSurfaceMtl(DisplayMtl *display,
428*8975f5c5SAndroid Build Coastguard Worker                                   const egl::SurfaceState &state,
429*8975f5c5SAndroid Build Coastguard Worker                                   EGLNativeWindowType window,
430*8975f5c5SAndroid Build Coastguard Worker                                   const egl::AttributeMap &attribs)
431*8975f5c5SAndroid Build Coastguard Worker    : SurfaceMtl(display, state, attribs), mLayer((__bridge CALayer *)(window))
432*8975f5c5SAndroid Build Coastguard Worker{
433*8975f5c5SAndroid Build Coastguard Worker    // NOTE(hqle): Width and height attributes is ignored for now.
434*8975f5c5SAndroid Build Coastguard Worker    mCurrentKnownDrawableSize = CGSizeMake(0, 0);
435*8975f5c5SAndroid Build Coastguard Worker}
436*8975f5c5SAndroid Build Coastguard Worker
437*8975f5c5SAndroid Build Coastguard WorkerWindowSurfaceMtl::~WindowSurfaceMtl() {}
438*8975f5c5SAndroid Build Coastguard Worker
439*8975f5c5SAndroid Build Coastguard Workervoid WindowSurfaceMtl::destroy(const egl::Display *display)
440*8975f5c5SAndroid Build Coastguard Worker{
441*8975f5c5SAndroid Build Coastguard Worker    SurfaceMtl::destroy(display);
442*8975f5c5SAndroid Build Coastguard Worker
443*8975f5c5SAndroid Build Coastguard Worker    mCurrentDrawable = nil;
444*8975f5c5SAndroid Build Coastguard Worker    if (mMetalLayer && mMetalLayer.get() != mLayer)
445*8975f5c5SAndroid Build Coastguard Worker    {
446*8975f5c5SAndroid Build Coastguard Worker        // If we created metal layer in WindowSurfaceMtl::initialize(),
447*8975f5c5SAndroid Build Coastguard Worker        // we need to detach it from super layer now.
448*8975f5c5SAndroid Build Coastguard Worker        [mMetalLayer.get() removeFromSuperlayer];
449*8975f5c5SAndroid Build Coastguard Worker    }
450*8975f5c5SAndroid Build Coastguard Worker    mMetalLayer = nil;
451*8975f5c5SAndroid Build Coastguard Worker}
452*8975f5c5SAndroid Build Coastguard Worker
453*8975f5c5SAndroid Build Coastguard Workeregl::Error WindowSurfaceMtl::initialize(const egl::Display *display)
454*8975f5c5SAndroid Build Coastguard Worker{
455*8975f5c5SAndroid Build Coastguard Worker    egl::Error re = SurfaceMtl::initialize(display);
456*8975f5c5SAndroid Build Coastguard Worker    if (re.isError())
457*8975f5c5SAndroid Build Coastguard Worker    {
458*8975f5c5SAndroid Build Coastguard Worker        return re;
459*8975f5c5SAndroid Build Coastguard Worker    }
460*8975f5c5SAndroid Build Coastguard Worker
461*8975f5c5SAndroid Build Coastguard Worker    DisplayMtl *displayMtl    = mtl::GetImpl(display);
462*8975f5c5SAndroid Build Coastguard Worker    id<MTLDevice> metalDevice = displayMtl->getMetalDevice();
463*8975f5c5SAndroid Build Coastguard Worker
464*8975f5c5SAndroid Build Coastguard Worker    StartFrameCapture(metalDevice, displayMtl->cmdQueue().get());
465*8975f5c5SAndroid Build Coastguard Worker
466*8975f5c5SAndroid Build Coastguard Worker    ANGLE_MTL_OBJC_SCOPE
467*8975f5c5SAndroid Build Coastguard Worker    {
468*8975f5c5SAndroid Build Coastguard Worker        if ([mLayer isKindOfClass:CAMetalLayer.class])
469*8975f5c5SAndroid Build Coastguard Worker        {
470*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer.retainAssign(static_cast<CAMetalLayer *>(mLayer));
471*8975f5c5SAndroid Build Coastguard Worker        }
472*8975f5c5SAndroid Build Coastguard Worker        else
473*8975f5c5SAndroid Build Coastguard Worker        {
474*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer             = [[[CAMetalLayer alloc] init] ANGLE_MTL_AUTORELEASE];
475*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer.get().frame = mLayer.frame;
476*8975f5c5SAndroid Build Coastguard Worker        }
477*8975f5c5SAndroid Build Coastguard Worker
478*8975f5c5SAndroid Build Coastguard Worker        mMetalLayer.get().device          = metalDevice;
479*8975f5c5SAndroid Build Coastguard Worker        mMetalLayer.get().pixelFormat     = mColorFormat.metalFormat;
480*8975f5c5SAndroid Build Coastguard Worker        mMetalLayer.get().framebufferOnly = NO;  // Support blitting and glReadPixels
481*8975f5c5SAndroid Build Coastguard Worker
482*8975f5c5SAndroid Build Coastguard Worker#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
483*8975f5c5SAndroid Build Coastguard Worker        // Autoresize with parent layer.
484*8975f5c5SAndroid Build Coastguard Worker        mMetalLayer.get().autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
485*8975f5c5SAndroid Build Coastguard Worker#endif
486*8975f5c5SAndroid Build Coastguard Worker        if (mMetalLayer.get() != mLayer)
487*8975f5c5SAndroid Build Coastguard Worker        {
488*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer.get().contentsScale = mLayer.contentsScale;
489*8975f5c5SAndroid Build Coastguard Worker
490*8975f5c5SAndroid Build Coastguard Worker            [mLayer addSublayer:mMetalLayer.get()];
491*8975f5c5SAndroid Build Coastguard Worker        }
492*8975f5c5SAndroid Build Coastguard Worker
493*8975f5c5SAndroid Build Coastguard Worker        // ensure drawableSize is set to correct value:
494*8975f5c5SAndroid Build Coastguard Worker        mMetalLayer.get().drawableSize = mCurrentKnownDrawableSize = calcExpectedDrawableSize();
495*8975f5c5SAndroid Build Coastguard Worker    }
496*8975f5c5SAndroid Build Coastguard Worker
497*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
498*8975f5c5SAndroid Build Coastguard Worker}
499*8975f5c5SAndroid Build Coastguard Worker
500*8975f5c5SAndroid Build Coastguard Workeregl::Error WindowSurfaceMtl::swap(const gl::Context *context)
501*8975f5c5SAndroid Build Coastguard Worker{
502*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TO_EGL_TRY(swapImpl(context));
503*8975f5c5SAndroid Build Coastguard Worker
504*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
505*8975f5c5SAndroid Build Coastguard Worker}
506*8975f5c5SAndroid Build Coastguard Worker
507*8975f5c5SAndroid Build Coastguard Workervoid WindowSurfaceMtl::setSwapInterval(const egl::Display *display, EGLint interval)
508*8975f5c5SAndroid Build Coastguard Worker{
509*8975f5c5SAndroid Build Coastguard Worker#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
510*8975f5c5SAndroid Build Coastguard Worker    mMetalLayer.get().displaySyncEnabled = interval != 0;
511*8975f5c5SAndroid Build Coastguard Worker#endif
512*8975f5c5SAndroid Build Coastguard Worker}
513*8975f5c5SAndroid Build Coastguard Worker
514*8975f5c5SAndroid Build Coastguard Worker// width and height can change with client window resizing
515*8975f5c5SAndroid Build Coastguard WorkerEGLint WindowSurfaceMtl::getWidth() const
516*8975f5c5SAndroid Build Coastguard Worker{
517*8975f5c5SAndroid Build Coastguard Worker    return static_cast<EGLint>(mCurrentKnownDrawableSize.width);
518*8975f5c5SAndroid Build Coastguard Worker}
519*8975f5c5SAndroid Build Coastguard Worker
520*8975f5c5SAndroid Build Coastguard WorkerEGLint WindowSurfaceMtl::getHeight() const
521*8975f5c5SAndroid Build Coastguard Worker{
522*8975f5c5SAndroid Build Coastguard Worker    return static_cast<EGLint>(mCurrentKnownDrawableSize.height);
523*8975f5c5SAndroid Build Coastguard Worker}
524*8975f5c5SAndroid Build Coastguard Worker
525*8975f5c5SAndroid Build Coastguard WorkerEGLint WindowSurfaceMtl::getSwapBehavior() const
526*8975f5c5SAndroid Build Coastguard Worker{
527*8975f5c5SAndroid Build Coastguard Worker    return EGL_BUFFER_DESTROYED;
528*8975f5c5SAndroid Build Coastguard Worker}
529*8975f5c5SAndroid Build Coastguard Worker
530*8975f5c5SAndroid Build Coastguard Workerangle::Result WindowSurfaceMtl::initializeContents(const gl::Context *context,
531*8975f5c5SAndroid Build Coastguard Worker                                                   GLenum binding,
532*8975f5c5SAndroid Build Coastguard Worker                                                   const gl::ImageIndex &imageIndex)
533*8975f5c5SAndroid Build Coastguard Worker{
534*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TRY(ensureCurrentDrawableObtained(context));
535*8975f5c5SAndroid Build Coastguard Worker    return SurfaceMtl::initializeContents(context, binding, imageIndex);
536*8975f5c5SAndroid Build Coastguard Worker}
537*8975f5c5SAndroid Build Coastguard Worker
538*8975f5c5SAndroid Build Coastguard Workerangle::Result WindowSurfaceMtl::getAttachmentRenderTarget(const gl::Context *context,
539*8975f5c5SAndroid Build Coastguard Worker                                                          GLenum binding,
540*8975f5c5SAndroid Build Coastguard Worker                                                          const gl::ImageIndex &imageIndex,
541*8975f5c5SAndroid Build Coastguard Worker                                                          GLsizei samples,
542*8975f5c5SAndroid Build Coastguard Worker                                                          FramebufferAttachmentRenderTarget **rtOut)
543*8975f5c5SAndroid Build Coastguard Worker{
544*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TRY(ensureCurrentDrawableObtained(context));
545*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TRY(ensureCompanionTexturesSizeCorrect(context));
546*8975f5c5SAndroid Build Coastguard Worker
547*8975f5c5SAndroid Build Coastguard Worker    return SurfaceMtl::getAttachmentRenderTarget(context, binding, imageIndex, samples, rtOut);
548*8975f5c5SAndroid Build Coastguard Worker}
549*8975f5c5SAndroid Build Coastguard Worker
550*8975f5c5SAndroid Build Coastguard Workeregl::Error WindowSurfaceMtl::attachToFramebuffer(const gl::Context *context,
551*8975f5c5SAndroid Build Coastguard Worker                                                 gl::Framebuffer *framebuffer)
552*8975f5c5SAndroid Build Coastguard Worker{
553*8975f5c5SAndroid Build Coastguard Worker    FramebufferMtl *framebufferMtl = GetImplAs<FramebufferMtl>(framebuffer);
554*8975f5c5SAndroid Build Coastguard Worker    ASSERT(!framebufferMtl->getBackbuffer());
555*8975f5c5SAndroid Build Coastguard Worker    framebufferMtl->setBackbuffer(this);
556*8975f5c5SAndroid Build Coastguard Worker    framebufferMtl->setFlipY(true);
557*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
558*8975f5c5SAndroid Build Coastguard Worker}
559*8975f5c5SAndroid Build Coastguard Worker
560*8975f5c5SAndroid Build Coastguard Workeregl::Error WindowSurfaceMtl::detachFromFramebuffer(const gl::Context *context,
561*8975f5c5SAndroid Build Coastguard Worker                                                   gl::Framebuffer *framebuffer)
562*8975f5c5SAndroid Build Coastguard Worker{
563*8975f5c5SAndroid Build Coastguard Worker    FramebufferMtl *framebufferMtl = GetImplAs<FramebufferMtl>(framebuffer);
564*8975f5c5SAndroid Build Coastguard Worker    ASSERT(framebufferMtl->getBackbuffer() == this);
565*8975f5c5SAndroid Build Coastguard Worker    framebufferMtl->setBackbuffer(nullptr);
566*8975f5c5SAndroid Build Coastguard Worker    framebufferMtl->setFlipY(false);
567*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
568*8975f5c5SAndroid Build Coastguard Worker}
569*8975f5c5SAndroid Build Coastguard Worker
570*8975f5c5SAndroid Build Coastguard Workerangle::Result WindowSurfaceMtl::ensureCurrentDrawableObtained(const gl::Context *context)
571*8975f5c5SAndroid Build Coastguard Worker{
572*8975f5c5SAndroid Build Coastguard Worker    if (!mCurrentDrawable)
573*8975f5c5SAndroid Build Coastguard Worker    {
574*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(obtainNextDrawable(context));
575*8975f5c5SAndroid Build Coastguard Worker    }
576*8975f5c5SAndroid Build Coastguard Worker
577*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
578*8975f5c5SAndroid Build Coastguard Worker}
579*8975f5c5SAndroid Build Coastguard Worker
580*8975f5c5SAndroid Build Coastguard Workerangle::Result WindowSurfaceMtl::ensureCompanionTexturesSizeCorrect(const gl::Context *context)
581*8975f5c5SAndroid Build Coastguard Worker{
582*8975f5c5SAndroid Build Coastguard Worker    ASSERT(mMetalLayer);
583*8975f5c5SAndroid Build Coastguard Worker
584*8975f5c5SAndroid Build Coastguard Worker    gl::Extents size(static_cast<int>(mMetalLayer.get().drawableSize.width),
585*8975f5c5SAndroid Build Coastguard Worker                     static_cast<int>(mMetalLayer.get().drawableSize.height), 1);
586*8975f5c5SAndroid Build Coastguard Worker
587*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TRY(SurfaceMtl::ensureCompanionTexturesSizeCorrect(context, size));
588*8975f5c5SAndroid Build Coastguard Worker
589*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
590*8975f5c5SAndroid Build Coastguard Worker}
591*8975f5c5SAndroid Build Coastguard Worker
592*8975f5c5SAndroid Build Coastguard Workerangle::Result WindowSurfaceMtl::ensureColorTextureReadyForReadPixels(const gl::Context *context)
593*8975f5c5SAndroid Build Coastguard Worker{
594*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TRY(ensureCurrentDrawableObtained(context));
595*8975f5c5SAndroid Build Coastguard Worker
596*8975f5c5SAndroid Build Coastguard Worker    if (mMSColorTexture)
597*8975f5c5SAndroid Build Coastguard Worker    {
598*8975f5c5SAndroid Build Coastguard Worker        if (mMSColorTexture->isCPUReadMemNeedSync())
599*8975f5c5SAndroid Build Coastguard Worker        {
600*8975f5c5SAndroid Build Coastguard Worker            ANGLE_TRY(resolveColorTextureIfNeeded(context));
601*8975f5c5SAndroid Build Coastguard Worker            mMSColorTexture->resetCPUReadMemNeedSync();
602*8975f5c5SAndroid Build Coastguard Worker        }
603*8975f5c5SAndroid Build Coastguard Worker    }
604*8975f5c5SAndroid Build Coastguard Worker
605*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
606*8975f5c5SAndroid Build Coastguard Worker}
607*8975f5c5SAndroid Build Coastguard Worker
608*8975f5c5SAndroid Build Coastguard WorkerCGSize WindowSurfaceMtl::calcExpectedDrawableSize() const
609*8975f5c5SAndroid Build Coastguard Worker{
610*8975f5c5SAndroid Build Coastguard Worker    CGSize currentLayerSize           = mMetalLayer.get().bounds.size;
611*8975f5c5SAndroid Build Coastguard Worker    CGFloat currentLayerContentsScale = mMetalLayer.get().contentsScale;
612*8975f5c5SAndroid Build Coastguard Worker    CGSize expectedDrawableSize = CGSizeMake(currentLayerSize.width * currentLayerContentsScale,
613*8975f5c5SAndroid Build Coastguard Worker                                             currentLayerSize.height * currentLayerContentsScale);
614*8975f5c5SAndroid Build Coastguard Worker
615*8975f5c5SAndroid Build Coastguard Worker    return expectedDrawableSize;
616*8975f5c5SAndroid Build Coastguard Worker}
617*8975f5c5SAndroid Build Coastguard Worker
618*8975f5c5SAndroid Build Coastguard Workerbool WindowSurfaceMtl::checkIfLayerResized(const gl::Context *context)
619*8975f5c5SAndroid Build Coastguard Worker{
620*8975f5c5SAndroid Build Coastguard Worker    if (mMetalLayer.get() != mLayer)
621*8975f5c5SAndroid Build Coastguard Worker    {
622*8975f5c5SAndroid Build Coastguard Worker        if (mMetalLayer.get().contentsScale != mLayer.contentsScale)
623*8975f5c5SAndroid Build Coastguard Worker        {
624*8975f5c5SAndroid Build Coastguard Worker            // Parent layer's content scale has changed, update Metal layer's scale factor.
625*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer.get().contentsScale = mLayer.contentsScale;
626*8975f5c5SAndroid Build Coastguard Worker        }
627*8975f5c5SAndroid Build Coastguard Worker#if !TARGET_OS_OSX && !TARGET_OS_MACCATALYST
628*8975f5c5SAndroid Build Coastguard Worker        // Only macOS supports autoresizing mask. Thus, the metal layer has to be manually
629*8975f5c5SAndroid Build Coastguard Worker        // updated.
630*8975f5c5SAndroid Build Coastguard Worker        if (!CGRectEqualToRect(mMetalLayer.get().bounds, mLayer.bounds))
631*8975f5c5SAndroid Build Coastguard Worker        {
632*8975f5c5SAndroid Build Coastguard Worker            // Parent layer's bounds has changed, update the Metal layer's bounds as well.
633*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer.get().bounds = mLayer.bounds;
634*8975f5c5SAndroid Build Coastguard Worker        }
635*8975f5c5SAndroid Build Coastguard Worker#endif
636*8975f5c5SAndroid Build Coastguard Worker    }
637*8975f5c5SAndroid Build Coastguard Worker
638*8975f5c5SAndroid Build Coastguard Worker    CGSize currentLayerDrawableSize = mMetalLayer.get().drawableSize;
639*8975f5c5SAndroid Build Coastguard Worker    CGSize expectedDrawableSize     = calcExpectedDrawableSize();
640*8975f5c5SAndroid Build Coastguard Worker
641*8975f5c5SAndroid Build Coastguard Worker    // NOTE(hqle): We need to compare the size against mCurrentKnownDrawableSize also.
642*8975f5c5SAndroid Build Coastguard Worker    // That is because metal framework might internally change the drawableSize property of
643*8975f5c5SAndroid Build Coastguard Worker    // metal layer, and it might become equal to expectedDrawableSize. If that happens, we cannot
644*8975f5c5SAndroid Build Coastguard Worker    // know whether the layer has been resized or not.
645*8975f5c5SAndroid Build Coastguard Worker    if (currentLayerDrawableSize.width != expectedDrawableSize.width ||
646*8975f5c5SAndroid Build Coastguard Worker        currentLayerDrawableSize.height != expectedDrawableSize.height ||
647*8975f5c5SAndroid Build Coastguard Worker        mCurrentKnownDrawableSize.width != expectedDrawableSize.width ||
648*8975f5c5SAndroid Build Coastguard Worker        mCurrentKnownDrawableSize.height != expectedDrawableSize.height)
649*8975f5c5SAndroid Build Coastguard Worker    {
650*8975f5c5SAndroid Build Coastguard Worker        // Resize the internal drawable texture.
651*8975f5c5SAndroid Build Coastguard Worker        mMetalLayer.get().drawableSize = mCurrentKnownDrawableSize = expectedDrawableSize;
652*8975f5c5SAndroid Build Coastguard Worker
653*8975f5c5SAndroid Build Coastguard Worker        return true;
654*8975f5c5SAndroid Build Coastguard Worker    }
655*8975f5c5SAndroid Build Coastguard Worker
656*8975f5c5SAndroid Build Coastguard Worker    return false;
657*8975f5c5SAndroid Build Coastguard Worker}
658*8975f5c5SAndroid Build Coastguard Worker
659*8975f5c5SAndroid Build Coastguard Workerangle::Result WindowSurfaceMtl::obtainNextDrawable(const gl::Context *context)
660*8975f5c5SAndroid Build Coastguard Worker{
661*8975f5c5SAndroid Build Coastguard Worker    ANGLE_MTL_OBJC_SCOPE
662*8975f5c5SAndroid Build Coastguard Worker    {
663*8975f5c5SAndroid Build Coastguard Worker        ContextMtl *contextMtl = mtl::GetImpl(context);
664*8975f5c5SAndroid Build Coastguard Worker
665*8975f5c5SAndroid Build Coastguard Worker        ANGLE_MTL_TRY(contextMtl, mMetalLayer);
666*8975f5c5SAndroid Build Coastguard Worker
667*8975f5c5SAndroid Build Coastguard Worker        // Check if layer was resized
668*8975f5c5SAndroid Build Coastguard Worker        if (checkIfLayerResized(context))
669*8975f5c5SAndroid Build Coastguard Worker        {
670*8975f5c5SAndroid Build Coastguard Worker            contextMtl->onBackbufferResized(context, this);
671*8975f5c5SAndroid Build Coastguard Worker        }
672*8975f5c5SAndroid Build Coastguard Worker
673*8975f5c5SAndroid Build Coastguard Worker        mCurrentDrawable.retainAssign([mMetalLayer nextDrawable]);
674*8975f5c5SAndroid Build Coastguard Worker        if (!mCurrentDrawable)
675*8975f5c5SAndroid Build Coastguard Worker        {
676*8975f5c5SAndroid Build Coastguard Worker            // The GPU might be taking too long finishing its rendering to the previous frame.
677*8975f5c5SAndroid Build Coastguard Worker            // Try again, indefinitely wait until the previous frame render finishes.
678*8975f5c5SAndroid Build Coastguard Worker            // TODO: this may wait forever here
679*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer.get().allowsNextDrawableTimeout = NO;
680*8975f5c5SAndroid Build Coastguard Worker            mCurrentDrawable.retainAssign([mMetalLayer nextDrawable]);
681*8975f5c5SAndroid Build Coastguard Worker            mMetalLayer.get().allowsNextDrawableTimeout = YES;
682*8975f5c5SAndroid Build Coastguard Worker        }
683*8975f5c5SAndroid Build Coastguard Worker
684*8975f5c5SAndroid Build Coastguard Worker        if (!mColorTexture)
685*8975f5c5SAndroid Build Coastguard Worker        {
686*8975f5c5SAndroid Build Coastguard Worker            mColorTexture = mtl::Texture::MakeFromMetal(mCurrentDrawable.get().texture);
687*8975f5c5SAndroid Build Coastguard Worker            ASSERT(!mColorRenderTarget.getTexture());
688*8975f5c5SAndroid Build Coastguard Worker            mColorRenderTarget.setWithImplicitMSTexture(mColorTexture, mMSColorTexture,
689*8975f5c5SAndroid Build Coastguard Worker                                                        mtl::kZeroNativeMipLevel, 0, mColorFormat);
690*8975f5c5SAndroid Build Coastguard Worker        }
691*8975f5c5SAndroid Build Coastguard Worker        else
692*8975f5c5SAndroid Build Coastguard Worker        {
693*8975f5c5SAndroid Build Coastguard Worker            mColorTexture->set(mCurrentDrawable.get().texture);
694*8975f5c5SAndroid Build Coastguard Worker        }
695*8975f5c5SAndroid Build Coastguard Worker        mColorTextureInitialized = false;
696*8975f5c5SAndroid Build Coastguard Worker
697*8975f5c5SAndroid Build Coastguard Worker        ANGLE_MTL_LOG("Current metal drawable size=%d,%d", mColorTexture->width(),
698*8975f5c5SAndroid Build Coastguard Worker                      mColorTexture->height());
699*8975f5c5SAndroid Build Coastguard Worker
700*8975f5c5SAndroid Build Coastguard Worker        // Now we have to resize depth stencil buffers if required.
701*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(ensureCompanionTexturesSizeCorrect(context));
702*8975f5c5SAndroid Build Coastguard Worker
703*8975f5c5SAndroid Build Coastguard Worker        return angle::Result::Continue;
704*8975f5c5SAndroid Build Coastguard Worker    }
705*8975f5c5SAndroid Build Coastguard Worker}
706*8975f5c5SAndroid Build Coastguard Worker
707*8975f5c5SAndroid Build Coastguard Workerangle::Result WindowSurfaceMtl::swapImpl(const gl::Context *context)
708*8975f5c5SAndroid Build Coastguard Worker{
709*8975f5c5SAndroid Build Coastguard Worker    if (mCurrentDrawable)
710*8975f5c5SAndroid Build Coastguard Worker    {
711*8975f5c5SAndroid Build Coastguard Worker        ASSERT(mColorTexture);
712*8975f5c5SAndroid Build Coastguard Worker
713*8975f5c5SAndroid Build Coastguard Worker        ContextMtl *contextMtl = mtl::GetImpl(context);
714*8975f5c5SAndroid Build Coastguard Worker
715*8975f5c5SAndroid Build Coastguard Worker        if (mMSColorTexture)
716*8975f5c5SAndroid Build Coastguard Worker        {
717*8975f5c5SAndroid Build Coastguard Worker            ANGLE_TRY(resolveColorTextureIfNeeded(context));
718*8975f5c5SAndroid Build Coastguard Worker        }
719*8975f5c5SAndroid Build Coastguard Worker
720*8975f5c5SAndroid Build Coastguard Worker        contextMtl->present(context, mCurrentDrawable);
721*8975f5c5SAndroid Build Coastguard Worker
722*8975f5c5SAndroid Build Coastguard Worker        StopFrameCapture();
723*8975f5c5SAndroid Build Coastguard Worker        StartFrameCapture(contextMtl);
724*8975f5c5SAndroid Build Coastguard Worker
725*8975f5c5SAndroid Build Coastguard Worker        // Invalidate current drawable
726*8975f5c5SAndroid Build Coastguard Worker        mColorTexture->set(nil);
727*8975f5c5SAndroid Build Coastguard Worker        mCurrentDrawable = nil;
728*8975f5c5SAndroid Build Coastguard Worker    }
729*8975f5c5SAndroid Build Coastguard Worker    // Robust resource init: should initialize stencil zero and depth to 1.0 after swap.
730*8975f5c5SAndroid Build Coastguard Worker    if (mDepthTexture || mStencilTexture)
731*8975f5c5SAndroid Build Coastguard Worker    {
732*8975f5c5SAndroid Build Coastguard Worker        mDepthStencilTexturesInitialized = false;
733*8975f5c5SAndroid Build Coastguard Worker    }
734*8975f5c5SAndroid Build Coastguard Worker    return angle::Result::Continue;
735*8975f5c5SAndroid Build Coastguard Worker}
736*8975f5c5SAndroid Build Coastguard Worker
737*8975f5c5SAndroid Build Coastguard Worker// OffscreenSurfaceMtl implementation
738*8975f5c5SAndroid Build Coastguard WorkerOffscreenSurfaceMtl::OffscreenSurfaceMtl(DisplayMtl *display,
739*8975f5c5SAndroid Build Coastguard Worker                                         const egl::SurfaceState &state,
740*8975f5c5SAndroid Build Coastguard Worker                                         const egl::AttributeMap &attribs)
741*8975f5c5SAndroid Build Coastguard Worker    : SurfaceMtl(display, state, attribs)
742*8975f5c5SAndroid Build Coastguard Worker{
743*8975f5c5SAndroid Build Coastguard Worker    mSize = gl::Extents(attribs.getAsInt(EGL_WIDTH, 1), attribs.getAsInt(EGL_HEIGHT, 1), 1);
744*8975f5c5SAndroid Build Coastguard Worker}
745*8975f5c5SAndroid Build Coastguard Worker
746*8975f5c5SAndroid Build Coastguard WorkerOffscreenSurfaceMtl::~OffscreenSurfaceMtl() {}
747*8975f5c5SAndroid Build Coastguard Worker
748*8975f5c5SAndroid Build Coastguard Workervoid OffscreenSurfaceMtl::destroy(const egl::Display *display)
749*8975f5c5SAndroid Build Coastguard Worker{
750*8975f5c5SAndroid Build Coastguard Worker    SurfaceMtl::destroy(display);
751*8975f5c5SAndroid Build Coastguard Worker}
752*8975f5c5SAndroid Build Coastguard Worker
753*8975f5c5SAndroid Build Coastguard WorkerEGLint OffscreenSurfaceMtl::getWidth() const
754*8975f5c5SAndroid Build Coastguard Worker{
755*8975f5c5SAndroid Build Coastguard Worker    return mSize.width;
756*8975f5c5SAndroid Build Coastguard Worker}
757*8975f5c5SAndroid Build Coastguard Worker
758*8975f5c5SAndroid Build Coastguard WorkerEGLint OffscreenSurfaceMtl::getHeight() const
759*8975f5c5SAndroid Build Coastguard Worker{
760*8975f5c5SAndroid Build Coastguard Worker    return mSize.height;
761*8975f5c5SAndroid Build Coastguard Worker}
762*8975f5c5SAndroid Build Coastguard Worker
763*8975f5c5SAndroid Build Coastguard Workeregl::Error OffscreenSurfaceMtl::swap(const gl::Context *context)
764*8975f5c5SAndroid Build Coastguard Worker{
765*8975f5c5SAndroid Build Coastguard Worker    // Check for surface resize.
766*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TO_EGL_TRY(ensureTexturesSizeCorrect(context));
767*8975f5c5SAndroid Build Coastguard Worker
768*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
769*8975f5c5SAndroid Build Coastguard Worker}
770*8975f5c5SAndroid Build Coastguard Worker
771*8975f5c5SAndroid Build Coastguard Workeregl::Error OffscreenSurfaceMtl::bindTexImage(const gl::Context *context,
772*8975f5c5SAndroid Build Coastguard Worker                                             gl::Texture *texture,
773*8975f5c5SAndroid Build Coastguard Worker                                             EGLint buffer)
774*8975f5c5SAndroid Build Coastguard Worker{
775*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
776*8975f5c5SAndroid Build Coastguard Worker    contextMtl->flushCommandBuffer(mtl::NoWait);
777*8975f5c5SAndroid Build Coastguard Worker
778*8975f5c5SAndroid Build Coastguard Worker    // Initialize offscreen textures if needed:
779*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TO_EGL_TRY(ensureTexturesSizeCorrect(context));
780*8975f5c5SAndroid Build Coastguard Worker
781*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
782*8975f5c5SAndroid Build Coastguard Worker}
783*8975f5c5SAndroid Build Coastguard Worker
784*8975f5c5SAndroid Build Coastguard Workeregl::Error OffscreenSurfaceMtl::releaseTexImage(const gl::Context *context, EGLint buffer)
785*8975f5c5SAndroid Build Coastguard Worker{
786*8975f5c5SAndroid Build Coastguard Worker    ContextMtl *contextMtl = mtl::GetImpl(context);
787*8975f5c5SAndroid Build Coastguard Worker
788*8975f5c5SAndroid Build Coastguard Worker    if (mMSColorTexture)
789*8975f5c5SAndroid Build Coastguard Worker    {
790*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TO_EGL_TRY(resolveColorTextureIfNeeded(context));
791*8975f5c5SAndroid Build Coastguard Worker    }
792*8975f5c5SAndroid Build Coastguard Worker
793*8975f5c5SAndroid Build Coastguard Worker    // NOTE(hqle): Should we finishCommandBuffer or flush is enough?
794*8975f5c5SAndroid Build Coastguard Worker    contextMtl->flushCommandBuffer(mtl::NoWait);
795*8975f5c5SAndroid Build Coastguard Worker    return egl::NoError();
796*8975f5c5SAndroid Build Coastguard Worker}
797*8975f5c5SAndroid Build Coastguard Worker
798*8975f5c5SAndroid Build Coastguard Workerangle::Result OffscreenSurfaceMtl::getAttachmentRenderTarget(
799*8975f5c5SAndroid Build Coastguard Worker    const gl::Context *context,
800*8975f5c5SAndroid Build Coastguard Worker    GLenum binding,
801*8975f5c5SAndroid Build Coastguard Worker    const gl::ImageIndex &imageIndex,
802*8975f5c5SAndroid Build Coastguard Worker    GLsizei samples,
803*8975f5c5SAndroid Build Coastguard Worker    FramebufferAttachmentRenderTarget **rtOut)
804*8975f5c5SAndroid Build Coastguard Worker{
805*8975f5c5SAndroid Build Coastguard Worker    // Initialize offscreen textures if needed:
806*8975f5c5SAndroid Build Coastguard Worker    ANGLE_TRY(ensureTexturesSizeCorrect(context));
807*8975f5c5SAndroid Build Coastguard Worker
808*8975f5c5SAndroid Build Coastguard Worker    return SurfaceMtl::getAttachmentRenderTarget(context, binding, imageIndex, samples, rtOut);
809*8975f5c5SAndroid Build Coastguard Worker}
810*8975f5c5SAndroid Build Coastguard Worker
811*8975f5c5SAndroid Build Coastguard Workerangle::Result OffscreenSurfaceMtl::ensureTexturesSizeCorrect(const gl::Context *context)
812*8975f5c5SAndroid Build Coastguard Worker{
813*8975f5c5SAndroid Build Coastguard Worker    if (!mColorTexture || mColorTexture->sizeAt0() != mSize)
814*8975f5c5SAndroid Build Coastguard Worker    {
815*8975f5c5SAndroid Build Coastguard Worker        ANGLE_TRY(CreateOrResizeTexture(context, mColorFormat, mSize.width, mSize.height, 1,
816*8975f5c5SAndroid Build Coastguard Worker                                        /** renderTargetOnly */ false, &mColorTexture));
817*8975f5c5SAndroid Build Coastguard Worker
818*8975f5c5SAndroid Build Coastguard Worker        mColorRenderTarget.set(mColorTexture, mtl::kZeroNativeMipLevel, 0, mColorFormat);
819*8975f5c5SAndroid Build Coastguard Worker    }
820*8975f5c5SAndroid Build Coastguard Worker
821*8975f5c5SAndroid Build Coastguard Worker    return ensureCompanionTexturesSizeCorrect(context, mSize);
822*8975f5c5SAndroid Build Coastguard Worker}
823*8975f5c5SAndroid Build Coastguard Worker
824*8975f5c5SAndroid Build Coastguard Worker// PBufferSurfaceMtl implementation
825*8975f5c5SAndroid Build Coastguard WorkerPBufferSurfaceMtl::PBufferSurfaceMtl(DisplayMtl *display,
826*8975f5c5SAndroid Build Coastguard Worker                                     const egl::SurfaceState &state,
827*8975f5c5SAndroid Build Coastguard Worker                                     const egl::AttributeMap &attribs)
828*8975f5c5SAndroid Build Coastguard Worker    : OffscreenSurfaceMtl(display, state, attribs)
829*8975f5c5SAndroid Build Coastguard Worker{}
830*8975f5c5SAndroid Build Coastguard Worker
831*8975f5c5SAndroid Build Coastguard Workervoid PBufferSurfaceMtl::setFixedWidth(EGLint width)
832*8975f5c5SAndroid Build Coastguard Worker{
833*8975f5c5SAndroid Build Coastguard Worker    mSize.width = width;
834*8975f5c5SAndroid Build Coastguard Worker}
835*8975f5c5SAndroid Build Coastguard Worker
836*8975f5c5SAndroid Build Coastguard Workervoid PBufferSurfaceMtl::setFixedHeight(EGLint height)
837*8975f5c5SAndroid Build Coastguard Worker{
838*8975f5c5SAndroid Build Coastguard Worker    mSize.height = height;
839*8975f5c5SAndroid Build Coastguard Worker}
840*8975f5c5SAndroid Build Coastguard Worker
841*8975f5c5SAndroid Build Coastguard Worker}  // namespace rx
842