//
// Copyright 2002 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.
//

// Surface.cpp: Implements the egl::Surface class, representing a drawing surface
// such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.

#include "libANGLE/Surface.h"

#include <EGL/eglext.h>

#include "libANGLE/Config.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/Texture.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/trace.h"

namespace egl
{
namespace
{
angle::SubjectIndex kSurfaceImplSubjectIndex = 0;
}  // namespace

SurfaceState::SurfaceState(SurfaceID idIn,
                           const egl::Config *configIn,
                           const AttributeMap &attributesIn)
    : id(idIn),
      label(nullptr),
      config((configIn != nullptr) ? new egl::Config(*configIn) : nullptr),
      attributes(attributesIn),
      timestampsEnabled(false),
      autoRefreshEnabled(false),
      directComposition(false),
      swapBehavior(EGL_NONE),
      swapInterval(0)
{
    directComposition = attributes.get(EGL_DIRECT_COMPOSITION_ANGLE, EGL_FALSE) == EGL_TRUE;
    swapInterval      = attributes.getAsInt(EGL_SWAP_INTERVAL_ANGLE, 1);
}

SurfaceState::~SurfaceState()
{
    delete config;
}

bool SurfaceState::isRobustResourceInitEnabled() const
{
    return attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE;
}

bool SurfaceState::hasProtectedContent() const
{
    return attributes.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) == EGL_TRUE;
}

Surface::Surface(EGLint surfaceType,
                 SurfaceID id,
                 const egl::Config *config,
                 const AttributeMap &attributes,
                 bool forceRobustResourceInit,
                 EGLenum buftype)
    : FramebufferAttachmentObject(),
      mState(id, config, attributes),
      mImplementation(nullptr),
      mRefCount(0),
      mDestroyed(false),
      mType(surfaceType),
      mBuftype(buftype),
      mPostSubBufferRequested(false),
      mLargestPbuffer(false),
      mGLColorspace(EGL_GL_COLORSPACE_LINEAR),
      mVGAlphaFormat(EGL_VG_ALPHA_FORMAT_NONPRE),
      mVGColorspace(EGL_VG_COLORSPACE_sRGB),
      mMipmapTexture(false),
      mMipmapLevel(0),
      mHorizontalResolution(EGL_UNKNOWN),
      mVerticalResolution(EGL_UNKNOWN),
      mMultisampleResolve(EGL_MULTISAMPLE_RESOLVE_DEFAULT),
      mFixedSize(false),
      mFixedWidth(0),
      mFixedHeight(0),
      mTextureFormat(TextureFormat::NoTexture),
      mTextureTarget(EGL_NO_TEXTURE),
      // FIXME: Determine actual pixel aspect ratio
      mPixelAspectRatio(static_cast<EGLint>(1.0 * EGL_DISPLAY_SCALING)),
      mRenderBuffer(EGL_BACK_BUFFER),
      mRequestedRenderBuffer(EGL_BACK_BUFFER),
      mRequestedSwapBehavior(mState.swapBehavior),
      mRequestedSwapInterval(mState.swapInterval),
      mOrientation(0),
      mTexture(nullptr),
      mColorFormat(config->renderTargetFormat),
      mDSFormat(config->depthStencilFormat),
      mIsCurrentOnAnyContext(false),
      mLockBufferPtr(nullptr),
      mLockBufferPitch(0),
      mBufferAgeQueriedSinceLastSwap(false),
      mIsDamageRegionSet(false),
      mColorInitState(gl::InitState::Initialized),
      mDepthStencilInitState(gl::InitState::Initialized),
      mImplObserverBinding(this, kSurfaceImplSubjectIndex)
{
    mPostSubBufferRequested =
        (attributes.get(EGL_POST_SUB_BUFFER_SUPPORTED_NV, EGL_FALSE) == EGL_TRUE);

    if (mType == EGL_PBUFFER_BIT)
    {
        mLargestPbuffer = (attributes.get(EGL_LARGEST_PBUFFER, EGL_FALSE) == EGL_TRUE);
    }

    if (mType == EGL_PIXMAP_BIT)
    {
        mRenderBuffer          = EGL_SINGLE_BUFFER;
        mRequestedRenderBuffer = EGL_SINGLE_BUFFER;
    }

    if (mType == EGL_WINDOW_BIT)
    {
        mRenderBuffer          = mState.attributes.getAsInt(EGL_RENDER_BUFFER, EGL_BACK_BUFFER);
        mRequestedRenderBuffer = mRenderBuffer;
    }

    mGLColorspace =
        static_cast<EGLenum>(attributes.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR));
    mVGAlphaFormat =
        static_cast<EGLenum>(attributes.get(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_NONPRE));
    mVGColorspace = static_cast<EGLenum>(attributes.get(EGL_VG_COLORSPACE, EGL_VG_COLORSPACE_sRGB));
    mMipmapTexture = (attributes.get(EGL_MIPMAP_TEXTURE, EGL_FALSE) == EGL_TRUE);

    mRobustResourceInitialization =
        forceRobustResourceInit ||
        (attributes.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
    if (mRobustResourceInitialization)
    {
        mColorInitState        = gl::InitState::MayNeedInit;
        mDepthStencilInitState = gl::InitState::MayNeedInit;
    }

    mFixedSize = (attributes.get(EGL_FIXED_SIZE_ANGLE, EGL_FALSE) == EGL_TRUE);
    if (mFixedSize)
    {
        mFixedWidth  = static_cast<size_t>(attributes.get(EGL_WIDTH, 0));
        mFixedHeight = static_cast<size_t>(attributes.get(EGL_HEIGHT, 0));
    }

    if (mType != EGL_WINDOW_BIT)
    {
        mTextureFormat = attributes.getAsPackedEnum(EGL_TEXTURE_FORMAT, TextureFormat::NoTexture);
        mTextureTarget = static_cast<EGLenum>(attributes.get(EGL_TEXTURE_TARGET, EGL_NO_TEXTURE));
    }

    mOrientation = static_cast<EGLint>(attributes.get(EGL_SURFACE_ORIENTATION_ANGLE, 0));

    mTextureOffset.x = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_X_ANGLE, 0));
    mTextureOffset.y = static_cast<int>(mState.attributes.get(EGL_TEXTURE_OFFSET_Y_ANGLE, 0));
}

Surface::~Surface() {}

rx::FramebufferAttachmentObjectImpl *Surface::getAttachmentImpl() const
{
    return mImplementation;
}

Error Surface::destroyImpl(const Display *display)
{
    if (mImplementation)
    {
        mImplementation->destroy(display);
    }

    ASSERT(!mTexture);

    SafeDelete(mImplementation);

    delete this;
    return NoError();
}

void Surface::postSwap(const gl::Context *context, const rx::SurfaceSwapFeedback &feedback)
{
    if (feedback.swapChainImageChanged)
    {
        context->onSwapChainImageChanged();
    }

    if (mRobustResourceInitialization && mState.swapBehavior != EGL_BUFFER_PRESERVED)
    {
        mColorInitState        = gl::InitState::MayNeedInit;
        mDepthStencilInitState = gl::InitState::MayNeedInit;
        onStateChange(angle::SubjectMessage::SubjectChanged);
    }

    mBufferAgeQueriedSinceLastSwap = false;

    mIsDamageRegionSet = false;
}

Error Surface::initialize(const Display *display)
{
    GLenum overrideRenderTargetFormat = mState.config->renderTargetFormat;

    // To account for color space differences, override the renderTargetFormat with the
    // non-linear format. If no suitable non-linear format was found, return
    // EGL_BAD_MATCH error
    if (!gl::ColorspaceFormatOverride(mGLColorspace, &overrideRenderTargetFormat))
    {
        return egl::Error(EGL_BAD_MATCH);
    }

    // If an override is required update mState.config as well
    if (mState.config->renderTargetFormat != overrideRenderTargetFormat)
    {
        egl::Config *overrideConfig        = new egl::Config(*(mState.config));
        overrideConfig->renderTargetFormat = overrideRenderTargetFormat;
        delete mState.config;
        mState.config = overrideConfig;

        mColorFormat = gl::Format(mState.config->renderTargetFormat);
        mDSFormat    = gl::Format(mState.config->depthStencilFormat);
    }

    ANGLE_TRY(mImplementation->initialize(display));

    // Initialized here since impl is nullptr in the constructor.
    // Must happen after implementation initialize for Android.
    mRequestedSwapBehavior = mState.swapBehavior = mImplementation->getSwapBehavior();

    // Update render buffer based on what the impl supports.
    if ((mType == EGL_WINDOW_BIT) && mRenderBuffer == EGL_SINGLE_BUFFER &&
        !mImplementation->supportsSingleRenderBuffer())
    {
        mRenderBuffer = EGL_BACK_BUFFER;
    }

    if (mBuftype == EGL_IOSURFACE_ANGLE)
    {
        GLenum internalFormat =
            static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE));
        GLenum type = static_cast<GLenum>(mState.attributes.get(EGL_TEXTURE_TYPE_ANGLE));

        // GL_RGBA + GL_HALF_FLOAT is not a valid format/type combination in GLES like it is in
        // desktop GL. Adjust the frontend format to be sized RGBA16F.
        if (internalFormat == GL_RGBA && type == GL_HALF_FLOAT)
        {
            internalFormat = GL_RGBA16F;
        }
        mColorFormat = gl::Format(internalFormat, type);
    }
    if (mBuftype == EGL_D3D_TEXTURE_ANGLE)
    {
        const angle::Format *colorFormat = mImplementation->getClientBufferTextureColorFormat();
        ASSERT(colorFormat != nullptr);
        GLenum internalFormat = colorFormat->fboImplementationInternalFormat;
        mColorFormat          = gl::Format(internalFormat, colorFormat->componentType);
        mGLColorspace         = EGL_GL_COLORSPACE_LINEAR;
        if (mColorFormat.info->colorEncoding == GL_SRGB)
        {
            mGLColorspace = EGL_GL_COLORSPACE_SRGB;
        }
    }

    if (mType == EGL_WINDOW_BIT && display->getExtensions().getFrameTimestamps)
    {
        mState.supportedCompositorTimings = mImplementation->getSupportedCompositorTimings();
        mState.supportedTimestamps        = mImplementation->getSupportedTimestamps();
    }

    mImplObserverBinding.bind(mImplementation);

    return NoError();
}

Error Surface::makeCurrent(const gl::Context *context)
{
    if (isLocked())
    {
        return egl::Error(EGL_BAD_ACCESS);
    }
    ANGLE_TRY(mImplementation->makeCurrent(context));
    mIsCurrentOnAnyContext = true;
    addRef();
    return NoError();
}

Error Surface::unMakeCurrent(const gl::Context *context)
{
    ANGLE_TRY(mImplementation->unMakeCurrent(context));
    mIsCurrentOnAnyContext = false;
    return releaseRef(context->getDisplay());
}

Error Surface::releaseRef(const Display *display)
{
    ASSERT(mRefCount > 0);
    mRefCount--;
    if (mRefCount == 0 && mDestroyed)
    {
        ASSERT(display);
        return destroyImpl(display);
    }

    return NoError();
}

Error Surface::onDestroy(const Display *display)
{
    mDestroyed = true;
    if (mRefCount == 0)
    {
        return destroyImpl(display);
    }
    return NoError();
}

void Surface::setLabel(EGLLabelKHR label)
{
    mState.label = label;
}

EGLLabelKHR Surface::getLabel() const
{
    return mState.label;
}

EGLint Surface::getType() const
{
    return mType;
}

Error Surface::prepareSwap(const gl::Context *context)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::prepareSwap");
    return mImplementation->prepareSwap(context);
}

Error Surface::swap(gl::Context *context)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swap");
    context->onPreSwap();

    context->getState().getOverlay()->onSwap();

    ANGLE_TRY(updatePropertiesOnSwap(context));

    rx::SurfaceSwapFeedback feedback;
    ANGLE_TRY_WITH_FINALLY(mImplementation->swap(context, &feedback), postSwap(context, feedback));
    return NoError();
}

Error Surface::swapWithDamage(gl::Context *context, const EGLint *rects, EGLint n_rects)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "egl::Surface::swapWithDamage");
    context->onPreSwap();

    context->getState().getOverlay()->onSwap();

    ANGLE_TRY(updatePropertiesOnSwap(context));

    rx::SurfaceSwapFeedback feedback;
    ANGLE_TRY_WITH_FINALLY(mImplementation->swapWithDamage(context, rects, n_rects, &feedback),
                           postSwap(context, feedback));
    return NoError();
}

Error Surface::postSubBuffer(const gl::Context *context,
                             EGLint x,
                             EGLint y,
                             EGLint width,
                             EGLint height)
{
    if (width == 0 || height == 0)
    {
        return egl::NoError();
    }

    context->getState().getOverlay()->onSwap();

    ANGLE_TRY(updatePropertiesOnSwap(context));
    ANGLE_TRY(mImplementation->postSubBuffer(context, x, y, width, height));
    rx::SurfaceSwapFeedback feedback;
    postSwap(context, feedback);
    return NoError();
}

Error Surface::setPresentationTime(EGLnsecsANDROID time)
{
    return mImplementation->setPresentationTime(time);
}

Error Surface::querySurfacePointerANGLE(EGLint attribute, void **value)
{
    return mImplementation->querySurfacePointerANGLE(attribute, value);
}

EGLint Surface::isPostSubBufferSupported() const
{
    return mPostSubBufferRequested && mImplementation->isPostSubBufferSupported();
}

void Surface::setRequestedSwapInterval(EGLint interval)
{
    mRequestedSwapInterval = interval;
}

void Surface::setSwapInterval(const Display *display, EGLint interval)
{
    mImplementation->setSwapInterval(display, interval);
    mState.swapInterval = interval;
}

void Surface::setMipmapLevel(EGLint level)
{
    // Level is set but ignored
    UNIMPLEMENTED();
    mMipmapLevel = level;
}

void Surface::setMultisampleResolve(EGLenum resolve)
{
    // Behaviour is set but ignored
    UNIMPLEMENTED();
    mMultisampleResolve = resolve;
}

void Surface::setRequestedSwapBehavior(EGLenum behavior)
{
    mRequestedSwapBehavior = behavior;
}

void Surface::setSwapBehavior(EGLenum behavior)
{
    mImplementation->setSwapBehavior(behavior);
    mState.swapBehavior = behavior;
}

void Surface::setFixedWidth(EGLint width)
{
    mFixedWidth = width;
    mImplementation->setFixedWidth(width);
}

void Surface::setFixedHeight(EGLint height)
{
    mFixedHeight = height;
    mImplementation->setFixedHeight(height);
}

const Config *Surface::getConfig() const
{
    return mState.config;
}

EGLint Surface::getPixelAspectRatio() const
{
    return mPixelAspectRatio;
}

EGLenum Surface::getRenderBuffer() const
{
    return mRenderBuffer;
}

EGLenum Surface::getRequestedRenderBuffer() const
{
    return mRequestedRenderBuffer;
}

EGLenum Surface::getSwapBehavior() const
{
    return mState.swapBehavior;
}

EGLenum Surface::getRequestedSwapBehavior() const
{
    return mRequestedSwapBehavior;
}

TextureFormat Surface::getTextureFormat() const
{
    return mTextureFormat;
}

EGLenum Surface::getTextureTarget() const
{
    return mTextureTarget;
}

bool Surface::getLargestPbuffer() const
{
    return mLargestPbuffer;
}

EGLenum Surface::getGLColorspace() const
{
    return mGLColorspace;
}

EGLenum Surface::getVGAlphaFormat() const
{
    return mVGAlphaFormat;
}

EGLenum Surface::getVGColorspace() const
{
    return mVGColorspace;
}

bool Surface::getMipmapTexture() const
{
    return mMipmapTexture;
}

EGLint Surface::getMipmapLevel() const
{
    return mMipmapLevel;
}

EGLint Surface::getHorizontalResolution() const
{
    return mHorizontalResolution;
}

EGLint Surface::getVerticalResolution() const
{
    return mVerticalResolution;
}

EGLenum Surface::getMultisampleResolve() const
{
    return mMultisampleResolve;
}

EGLint Surface::isFixedSize() const
{
    return mFixedSize;
}

gl::Extents Surface::getSize() const
{
    return mFixedSize
               ? gl::Extents(static_cast<EGLint>(mFixedWidth), static_cast<EGLint>(mFixedHeight), 1)
               : mImplementation->getSize();
}

egl::Error Surface::getUserSize(const egl::Display *display, EGLint *width, EGLint *height) const
{
    ASSERT(width != nullptr || height != nullptr);
    if (mFixedSize)
    {
        if (width != nullptr)
        {
            *width = static_cast<EGLint>(mFixedWidth);
        }
        if (height != nullptr)
        {
            *height = static_cast<EGLint>(mFixedHeight);
        }
        return NoError();
    }
    else
    {
        return mImplementation->getUserSize(display, width, height);
    }
}

Error Surface::bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer)
{
    ASSERT(!mTexture);
    ANGLE_TRY(mImplementation->bindTexImage(context, texture, buffer));
    Surface *previousSurface = texture->getBoundSurface();
    if (previousSurface != nullptr)
    {
        ANGLE_TRY(previousSurface->releaseTexImage(context, buffer));
    }
    if (texture->bindTexImageFromSurface(context, this) == angle::Result::Stop)
    {
        return Error(EGL_BAD_SURFACE);
    }
    mTexture = texture;
    addRef();

    return NoError();
}

Error Surface::releaseTexImage(const gl::Context *context, EGLint buffer)
{
    ASSERT(context);

    ANGLE_TRY(mImplementation->releaseTexImage(context, buffer));

    ASSERT(mTexture);
    ANGLE_TRY(ResultToEGL(mTexture->releaseTexImageFromSurface(context)));

    return releaseTexImageFromTexture(context);
}

Error Surface::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc)
{
    return mImplementation->getSyncValues(ust, msc, sbc);
}

Error Surface::getMscRate(EGLint *numerator, EGLint *denominator)
{
    return mImplementation->getMscRate(numerator, denominator);
}

Error Surface::releaseTexImageFromTexture(const gl::Context *context)
{
    ASSERT(mTexture);
    mTexture = nullptr;
    return releaseRef(context->getDisplay());
}

angle::Result Surface::ensureSizeResolved(const gl::Context *context) const
{
    return mImplementation->ensureSizeResolved(context);
}

bool Surface::isAttachmentSpecified(const gl::ImageIndex & /*imageIndex*/) const
{
    // Surface is always specified even if it has 0 sizes.
    return true;
}

gl::Extents Surface::getAttachmentSize(const gl::ImageIndex & /*target*/) const
{
    return getSize();
}

gl::Format Surface::getAttachmentFormat(GLenum binding, const gl::ImageIndex &target) const
{
    return (binding == GL_BACK ? mColorFormat : mDSFormat);
}

GLsizei Surface::getAttachmentSamples(const gl::ImageIndex &target) const
{
    return getConfig()->samples;
}

bool Surface::isRenderable(const gl::Context *context,
                           GLenum binding,
                           const gl::ImageIndex &imageIndex) const
{
    return true;
}

bool Surface::isYUV() const
{
    // EGL_EXT_yuv_surface is not implemented.
    return false;
}

bool Surface::isExternalImageWithoutIndividualSync() const
{
    return false;
}

bool Surface::hasFrontBufferUsage() const
{
    return false;
}

GLuint Surface::getId() const
{
    return mState.id.value;
}

Error Surface::getBufferAgeImpl(const gl::Context *context, EGLint *age) const
{
    return mImplementation->getBufferAge(context, age);
}

Error Surface::getBufferAge(const gl::Context *context, EGLint *age)
{
    Error err = getBufferAgeImpl(context, age);
    if (!err.isError())
    {
        mBufferAgeQueriedSinceLastSwap = true;
    }
    return err;
}

gl::InitState Surface::initState(GLenum binding, const gl::ImageIndex & /*imageIndex*/) const
{
    switch (binding)
    {
        case GL_BACK:
            return mColorInitState;
        case GL_DEPTH:
        case GL_STENCIL:
            return mDepthStencilInitState;
        default:
            UNREACHABLE();
            return gl::InitState::Initialized;
    }
}

void Surface::setInitState(GLenum binding,
                           const gl::ImageIndex & /*imageIndex*/,
                           gl::InitState initState)
{
    switch (binding)
    {
        case GL_BACK:
            mColorInitState = initState;
            break;
        case GL_DEPTH:
        case GL_STENCIL:
            mDepthStencilInitState = initState;
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void Surface::setTimestampsEnabled(bool enabled)
{
    mImplementation->setTimestampsEnabled(enabled);
    mState.timestampsEnabled = enabled;
}

bool Surface::isTimestampsEnabled() const
{
    return mState.timestampsEnabled;
}

Error Surface::setAutoRefreshEnabled(bool enabled)
{
    ANGLE_TRY(mImplementation->setAutoRefreshEnabled(enabled));
    mState.autoRefreshEnabled = enabled;
    return NoError();
}

bool Surface::hasProtectedContent() const
{
    return mState.hasProtectedContent();
}

const SupportedCompositorTiming &Surface::getSupportedCompositorTimings() const
{
    return mState.supportedCompositorTimings;
}

Error Surface::getCompositorTiming(EGLint numTimestamps,
                                   const EGLint *names,
                                   EGLnsecsANDROID *values) const
{
    return mImplementation->getCompositorTiming(numTimestamps, names, values);
}

Error Surface::getNextFrameId(EGLuint64KHR *frameId) const
{
    return mImplementation->getNextFrameId(frameId);
}

const SupportedTimestamps &Surface::getSupportedTimestamps() const
{
    return mState.supportedTimestamps;
}

Error Surface::getFrameTimestamps(EGLuint64KHR frameId,
                                  EGLint numTimestamps,
                                  const EGLint *timestamps,
                                  EGLnsecsANDROID *values) const
{
    return mImplementation->getFrameTimestamps(frameId, numTimestamps, timestamps, values);
}

void Surface::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
{
    ASSERT(index == kSurfaceImplSubjectIndex);
    switch (message)
    {
        case angle::SubjectMessage::SubjectChanged:
            onStateChange(angle::SubjectMessage::ContentsChanged);
            break;
        case angle::SubjectMessage::SurfaceChanged:
            onStateChange(angle::SubjectMessage::SurfaceChanged);
            break;
        default:
            UNREACHABLE();
            break;
    }
}

Error Surface::setRenderBuffer(EGLint renderBuffer)
{
    ANGLE_TRY(mImplementation->setRenderBuffer(renderBuffer));
    mRenderBuffer = renderBuffer;
    return NoError();
}

void Surface::setRequestedRenderBuffer(EGLint requestedRenderBuffer)
{
    mRequestedRenderBuffer = requestedRenderBuffer;
}

Error Surface::updatePropertiesOnSwap(const gl::Context *context)
{
    if ((mRenderBuffer != mRequestedRenderBuffer) &&
        context->getDisplay()->getExtensions().mutableRenderBufferKHR &&
        (getConfig()->surfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR))
    {
        ANGLE_TRY(setRenderBuffer(mRequestedRenderBuffer));
    }
    if (mState.swapInterval != mRequestedSwapInterval)
    {
        setSwapInterval(context->getDisplay(), mRequestedSwapInterval);
    }
    if (mState.swapBehavior != mRequestedSwapBehavior)
    {
        setSwapBehavior(mRequestedSwapBehavior);
    }
    return NoError();
}

bool Surface::isLocked() const
{
    return (mLockBufferPtr != nullptr);
}

EGLint Surface::getBitmapPitch() const
{
    return mLockBufferPitch;
}

EGLint Surface::getBitmapOrigin() const
{
    return mImplementation->origin();
}

EGLint Surface::getRedOffset() const
{
    const gl::InternalFormat &format = *mColorFormat.info;
    if (gl::IsBGRAFormat(format.internalFormat))
    {
        return format.blueBits + format.greenBits;
    }
    else
    {
        return 0;
    }
}

EGLint Surface::getGreenOffset() const
{
    const gl::InternalFormat &format = *mColorFormat.info;
    if (gl::IsBGRAFormat(format.internalFormat))
    {
        return format.blueBits;
    }
    else
    {
        return format.redBits;
    }
}

EGLint Surface::getBlueOffset() const
{
    const gl::InternalFormat &format = *mColorFormat.info;
    if (gl::IsBGRAFormat(format.internalFormat))
    {
        return 0;
    }
    else
    {
        return format.redBits + format.greenBits;
    }
}

EGLint Surface::getAlphaOffset() const
{
    const gl::InternalFormat &format = *mColorFormat.info;
    if (format.isLUMA())
    {
        return format.luminanceBits;  // Luma always first, alpha optional
    }
    // For RGBA/BGRA alpha is last
    return format.blueBits + format.greenBits + format.redBits;
}

EGLint Surface::getLuminanceOffset() const
{
    return 0;
}

EGLint Surface::getBitmapPixelSize() const
{
    constexpr EGLint kBitsPerByte    = 8;
    const gl::InternalFormat &format = *mColorFormat.info;
    return (format.pixelBytes * kBitsPerByte);
}

EGLAttribKHR Surface::getBitmapPointer() const
{
    return static_cast<EGLAttribKHR>((intptr_t)mLockBufferPtr);
}

egl::Error Surface::getCompressionRate(const egl::Display *display,
                                       const gl::Context *context,
                                       EGLint *rate)
{
    return mImplementation->getCompressionRate(display, context, rate);
}

egl::Error Surface::lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes)
{
    EGLint lockBufferUsageHint = attributes.getAsInt(
        EGL_LOCK_USAGE_HINT_KHR, (EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR));

    bool preservePixels = ((attributes.getAsInt(EGL_MAP_PRESERVE_PIXELS_KHR, false) == EGL_TRUE) ||
                           (mState.swapBehavior == EGL_BUFFER_PRESERVED));

    return mImplementation->lockSurface(display, lockBufferUsageHint, preservePixels,
                                        &mLockBufferPtr, &mLockBufferPitch);
}

egl::Error Surface::unlockSurfaceKHR(const egl::Display *display)
{
    mLockBufferPtr   = nullptr;
    mLockBufferPitch = 0;
    return mImplementation->unlockSurface(display, true);
}

WindowSurface::WindowSurface(rx::EGLImplFactory *implFactory,
                             SurfaceID id,
                             const egl::Config *config,
                             EGLNativeWindowType window,
                             const AttributeMap &attribs,
                             bool robustResourceInit)
    : Surface(EGL_WINDOW_BIT, id, config, attribs, robustResourceInit)
{
    mImplementation = implFactory->createWindowSurface(mState, window, attribs);
}

void Surface::setDamageRegion(const EGLint *rects, EGLint n_rects)
{
    mIsDamageRegionSet = true;
}

WindowSurface::~WindowSurface() {}

PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
                               SurfaceID id,
                               const Config *config,
                               const AttributeMap &attribs,
                               bool robustResourceInit)
    : Surface(EGL_PBUFFER_BIT, id, config, attribs, robustResourceInit)
{
    mImplementation = implFactory->createPbufferSurface(mState, attribs);
}

PbufferSurface::PbufferSurface(rx::EGLImplFactory *implFactory,
                               SurfaceID id,
                               const Config *config,
                               EGLenum buftype,
                               EGLClientBuffer clientBuffer,
                               const AttributeMap &attribs,
                               bool robustResourceInit)
    : Surface(EGL_PBUFFER_BIT, id, config, attribs, robustResourceInit, buftype)
{
    mImplementation =
        implFactory->createPbufferFromClientBuffer(mState, buftype, clientBuffer, attribs);
}

PbufferSurface::~PbufferSurface() {}

PixmapSurface::PixmapSurface(rx::EGLImplFactory *implFactory,
                             SurfaceID id,
                             const Config *config,
                             NativePixmapType nativePixmap,
                             const AttributeMap &attribs,
                             bool robustResourceInit)
    : Surface(EGL_PIXMAP_BIT, id, config, attribs, robustResourceInit)
{
    mImplementation = implFactory->createPixmapSurface(mState, nativePixmap, attribs);
}

PixmapSurface::~PixmapSurface() {}

// SurfaceDeleter implementation.

SurfaceDeleter::SurfaceDeleter(const Display *display) : mDisplay(display) {}

SurfaceDeleter::~SurfaceDeleter() {}

void SurfaceDeleter::operator()(Surface *surface)
{
    ANGLE_SWALLOW_ERR(surface->onDestroy(mDisplay));
}

}  // namespace egl
