//
// 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.h: Defines 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.

#ifndef LIBANGLE_SURFACE_H_
#define LIBANGLE_SURFACE_H_

#include <memory>

#include <EGL/egl.h>

#include "common/PackedEnums.h"
#include "common/angleutils.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Image.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/SurfaceImpl.h"

namespace gl
{
class Context;
class Framebuffer;
class Texture;
}  // namespace gl

namespace rx
{
class EGLImplFactory;
}

namespace egl
{
class Display;
struct Config;

using SupportedCompositorTiming = angle::PackedEnumBitSet<CompositorTiming>;
using SupportedTimestamps       = angle::PackedEnumBitSet<Timestamp>;

struct SurfaceState final : private angle::NonCopyable
{
    SurfaceState(SurfaceID idIn, const egl::Config *configIn, const AttributeMap &attributesIn);
    ~SurfaceState();

    bool isRobustResourceInitEnabled() const;
    bool hasProtectedContent() const;

    gl::OwnerImageIndex toOwnerIndex(const gl::ImageIndex &index) const
    {
        // Surfaces cannot be an EGL image sibling, so the translation is no-op.
        return ImageSourceAttributes{}.toOwnerIndex(index);
    }

    SurfaceID id;

    EGLLabelKHR label;
    const egl::Config *config;
    AttributeMap attributes;

    bool timestampsEnabled;
    bool autoRefreshEnabled;
    SupportedCompositorTiming supportedCompositorTimings;
    SupportedTimestamps supportedTimestamps;
    bool directComposition;
    EGLenum swapBehavior;
    EGLint swapInterval;
};

class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
{
  public:
    rx::SurfaceImpl *getImplementation() const { return mImplementation; }

    void setLabel(EGLLabelKHR label) override;
    EGLLabelKHR getLabel() const override;

    EGLint getType() const;

    Error initialize(const Display *display);
    Error makeCurrent(const gl::Context *context);
    Error unMakeCurrent(const gl::Context *context);
    Error prepareSwap(const gl::Context *context);
    Error swap(gl::Context *context);
    Error swapWithDamage(gl::Context *context, const EGLint *rects, EGLint n_rects);
    Error postSubBuffer(const gl::Context *context,
                        EGLint x,
                        EGLint y,
                        EGLint width,
                        EGLint height);
    Error setPresentationTime(EGLnsecsANDROID time);
    Error querySurfacePointerANGLE(EGLint attribute, void **value);
    Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer);
    Error releaseTexImage(const gl::Context *context, EGLint buffer);

    Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc);
    Error getMscRate(EGLint *numerator, EGLint *denominator);

    EGLint isPostSubBufferSupported() const;

    void setRequestedSwapInterval(EGLint interval);
    void setSwapInterval(const Display *display, EGLint interval);
    Error onDestroy(const Display *display);

    void setMipmapLevel(EGLint level);
    void setMultisampleResolve(EGLenum resolve);
    void setRequestedSwapBehavior(EGLenum behavior);
    void setSwapBehavior(EGLenum behavior);

    void setFixedWidth(EGLint width);
    void setFixedHeight(EGLint height);

    const Config *getConfig() const;

    // size can change with client window resizing
    // Size must be resolved before the call either during state synchronization or explicitly.
    gl::Extents getSize() const;
    // Unresolved Surface size until render target is first accessed (e.g. after draw).
    egl::Error getUserSize(const egl::Display *display, EGLint *width, EGLint *height) const;
    EGLint getPixelAspectRatio() const;
    EGLenum getRenderBuffer() const;
    EGLenum getRequestedRenderBuffer() const;
    EGLenum getSwapBehavior() const;
    EGLenum getRequestedSwapBehavior() const;
    TextureFormat getTextureFormat() const;
    EGLenum getTextureTarget() const;
    bool getLargestPbuffer() const;
    EGLenum getGLColorspace() const;
    EGLenum getVGAlphaFormat() const;
    EGLenum getVGColorspace() const;
    bool getMipmapTexture() const;
    EGLint getMipmapLevel() const;
    EGLint getHorizontalResolution() const;
    EGLint getVerticalResolution() const;
    EGLenum getMultisampleResolve() const;
    bool hasProtectedContent() const override;
    bool hasFoveatedRendering() const override { return false; }
    const gl::FoveationState *getFoveationState() const override { return nullptr; }

    // For lock surface buffer
    EGLint getBitmapPitch() const;
    EGLint getBitmapOrigin() const;
    EGLint getRedOffset() const;
    EGLint getGreenOffset() const;
    EGLint getBlueOffset() const;
    EGLint getAlphaOffset() const;
    EGLint getLuminanceOffset() const;
    EGLint getBitmapPixelSize() const;
    EGLAttribKHR getBitmapPointer() const;
    egl::Error getCompressionRate(const egl::Display *display,
                                  const gl::Context *context,
                                  EGLint *rate);
    egl::Error lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes);
    egl::Error unlockSurfaceKHR(const egl::Display *display);

    bool isLocked() const;
    bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; }

    gl::Texture *getBoundTexture() const { return mTexture; }

    EGLint isFixedSize() const;

    // FramebufferAttachmentObject implementation
    // Explicitly resolves surface size to use before state synchronization (e.g. validation).
    angle::Result ensureSizeResolved(const gl::Context *context) const override;
    bool isAttachmentSpecified(const gl::ImageIndex &imageIndex) const override;
    gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override;
    gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override;
    GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override;
    bool isRenderable(const gl::Context *context,
                      GLenum binding,
                      const gl::ImageIndex &imageIndex) const override;
    bool isYUV() const override;
    bool isExternalImageWithoutIndividualSync() const override;
    bool hasFrontBufferUsage() const override;

    void onAttach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {}
    void onDetach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {}
    SurfaceID id() const { return mState.id; }
    GLuint getId() const override;

    EGLint getOrientation() const { return mOrientation; }

    bool directComposition() const { return mState.directComposition; }

    gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override;
    void setInitState(GLenum binding,
                      const gl::ImageIndex &imageIndex,
                      gl::InitState initState) override;

    bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; }

    const gl::Format &getBindTexImageFormat() const { return mColorFormat; }

    // EGL_ANDROID_get_frame_timestamps entry points
    void setTimestampsEnabled(bool enabled);
    bool isTimestampsEnabled() const;

    // EGL_ANDROID_front_buffer_auto_refresh entry points
    Error setAutoRefreshEnabled(bool enabled);

    const SupportedCompositorTiming &getSupportedCompositorTimings() const;
    Error getCompositorTiming(EGLint numTimestamps,
                              const EGLint *names,
                              EGLnsecsANDROID *values) const;

    Error getNextFrameId(EGLuint64KHR *frameId) const;
    const SupportedTimestamps &getSupportedTimestamps() const;
    Error getFrameTimestamps(EGLuint64KHR frameId,
                             EGLint numTimestamps,
                             const EGLint *timestamps,
                             EGLnsecsANDROID *values) const;

    // Returns the offset into the texture backing the surface if specified via texture offset
    // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset
    // otherwise.
    const gl::Offset &getTextureOffset() const { return mTextureOffset; }

    Error getBufferAge(const gl::Context *context, EGLint *age);

    Error setRenderBuffer(EGLint renderBuffer);
    void setRequestedRenderBuffer(EGLint requestedRenderBuffer);

    bool bufferAgeQueriedSinceLastSwap() const { return mBufferAgeQueriedSinceLastSwap; }
    void setDamageRegion(const EGLint *rects, EGLint n_rects);
    bool isDamageRegionSet() const { return mIsDamageRegionSet; }

    void addRef() { mRefCount++; }
    void release()
    {
        ASSERT(mRefCount > 0);
        mRefCount--;
    }
    bool isReferenced() const { return mRefCount > 0; }

  protected:
    Surface(EGLint surfaceType,
            SurfaceID id,
            const egl::Config *config,
            const AttributeMap &attributes,
            bool forceRobustResourceInit,
            EGLenum buftype = EGL_NONE);
    ~Surface() override;
    rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;

    // ANGLE-only method, used internally
    friend class gl::Texture;
    Error releaseTexImageFromTexture(const gl::Context *context);

    SurfaceState mState;
    rx::SurfaceImpl *mImplementation;
    int mRefCount;
    bool mDestroyed;

    EGLint mType;
    EGLenum mBuftype;

    bool mPostSubBufferRequested;

    bool mLargestPbuffer;
    EGLenum mGLColorspace;
    EGLenum mVGAlphaFormat;
    EGLenum mVGColorspace;
    bool mMipmapTexture;
    EGLint mMipmapLevel;
    EGLint mHorizontalResolution;
    EGLint mVerticalResolution;
    EGLenum mMultisampleResolve;

    bool mFixedSize;
    size_t mFixedWidth;
    size_t mFixedHeight;

    bool mRobustResourceInitialization;

    TextureFormat mTextureFormat;
    EGLenum mTextureTarget;

    EGLint mPixelAspectRatio;        // Display aspect ratio
    EGLenum mRenderBuffer;           // Render buffer
    EGLenum mRequestedRenderBuffer;  // Requested render buffer
    EGLenum mRequestedSwapBehavior;
    EGLint mRequestedSwapInterval;

    EGLint mOrientation;

    // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a
    // Texture is deleted the Surface is unbound in onDestroy.
    gl::Texture *mTexture;

    gl::Format mColorFormat;
    gl::Format mDSFormat;

    gl::Offset mTextureOffset;

    bool mIsCurrentOnAnyContext;  // The surface is current to a context/client API
    uint8_t *mLockBufferPtr;      // Memory owned by backend.
    EGLint mLockBufferPitch;

    bool mBufferAgeQueriedSinceLastSwap;
    bool mIsDamageRegionSet;

  private:
    Error getBufferAgeImpl(const gl::Context *context, EGLint *age) const;

    Error destroyImpl(const Display *display);

    void postSwap(const gl::Context *context, const rx::SurfaceSwapFeedback &feedback);
    Error releaseRef(const Display *display);

    // ObserverInterface implementation.
    void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;

    Error updatePropertiesOnSwap(const gl::Context *context);

    gl::InitState mColorInitState;
    gl::InitState mDepthStencilInitState;
    angle::ObserverBinding mImplObserverBinding;
};

class WindowSurface final : public Surface
{
  public:
    WindowSurface(rx::EGLImplFactory *implFactory,
                  SurfaceID id,
                  const Config *config,
                  EGLNativeWindowType window,
                  const AttributeMap &attribs,
                  bool robustResourceInit);
    ~WindowSurface() override;
};

class PbufferSurface final : public Surface
{
  public:
    PbufferSurface(rx::EGLImplFactory *implFactory,
                   SurfaceID id,
                   const Config *config,
                   const AttributeMap &attribs,
                   bool robustResourceInit);
    PbufferSurface(rx::EGLImplFactory *implFactory,
                   SurfaceID id,
                   const Config *config,
                   EGLenum buftype,
                   EGLClientBuffer clientBuffer,
                   const AttributeMap &attribs,
                   bool robustResourceInit);

  protected:
    ~PbufferSurface() override;
};

class PixmapSurface final : public Surface
{
  public:
    PixmapSurface(rx::EGLImplFactory *implFactory,
                  SurfaceID id,
                  const Config *config,
                  NativePixmapType nativePixmap,
                  const AttributeMap &attribs,
                  bool robustResourceInit);

  protected:
    ~PixmapSurface() override;
};

class [[nodiscard]] ScopedSurfaceRef
{
  public:
    ScopedSurfaceRef(Surface *surface) : mSurface(surface)
    {
        if (mSurface)
        {
            mSurface->addRef();
        }
    }
    ~ScopedSurfaceRef()
    {
        if (mSurface)
        {
            mSurface->release();
        }
    }

  private:
    Surface *const mSurface;
};

class SurfaceDeleter final
{
  public:
    SurfaceDeleter(const Display *display);
    ~SurfaceDeleter();
    void operator()(Surface *surface);

  private:
    const Display *mDisplay;
};

using SurfacePointer = std::unique_ptr<Surface, SurfaceDeleter>;

}  // namespace egl

#endif  // LIBANGLE_SURFACE_H_
