diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/angle/checkout/src/libANGLE/Surface.h | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/Surface.h b/gfx/angle/checkout/src/libANGLE/Surface.h new file mode 100644 index 0000000000..862d2f57b2 --- /dev/null +++ b/gfx/angle/checkout/src/libANGLE/Surface.h @@ -0,0 +1,388 @@ +// +// 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/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(const egl::Config *configIn, const AttributeMap &attributesIn); + ~SurfaceState(); + + bool isRobustResourceInitEnabled() const; + bool hasProtectedContent() const; + EGLint getPreferredSwapInterval() const; + + EGLLabelKHR label; + const egl::Config *config; + AttributeMap attributes; + + bool timestampsEnabled; + bool autoRefreshEnabled; + SupportedCompositorTiming supportedCompositorTimings; + SupportedTimestamps supportedTimestamps; + bool directComposition; + EGLenum swapBehavior; +}; + +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(const gl::Context *context); + Error swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects); + Error swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken); + 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 setSwapInterval(EGLint interval); + Error onDestroy(const Display *display); + + void setMipmapLevel(EGLint level); + void setMultisampleResolve(EGLenum resolve); + void setSwapBehavior(EGLenum behavior); + + void setFixedWidth(EGLint width); + void setFixedHeight(EGLint height); + + const Config *getConfig() const; + + // width and height can change with client window resizing + EGLint getWidth() const; + EGLint getHeight() const; + // Note: windows cannot be resized on Android. The approach requires + // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is + // expensive; and there are troublesome timing issues for other parts of + // ANGLE (which cause test failures and crashes). Therefore, a + // special-Android-only path is created just for the querying of EGL_WIDTH + // and EGL_HEIGHT. + // https://issuetracker.google.com/issues/153329980 + egl::Error getUserWidth(const egl::Display *display, EGLint *value) const; + egl::Error getUserHeight(const egl::Display *display, EGLint *value) const; + EGLint getPixelAspectRatio() const; + EGLenum getRenderBuffer() const; + EGLenum getSwapBehavior() 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; + + // 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 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 + 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 isCreatedWithAHB() const override; + + void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override {} + void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override {} + 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); + + 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--; + } + + protected: + Surface(EGLint surfaceType, + GLuint serialId, + 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 + + 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); + Error releaseRef(const Display *display); + + // ObserverInterface implementation. + void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; + + gl::InitState mColorInitState; + gl::InitState mDepthStencilInitState; + angle::ObserverBinding mImplObserverBinding; + + GLuint mSerialId; +}; + +class WindowSurface final : public Surface +{ + public: + WindowSurface(rx::EGLImplFactory *implFactory, + const Config *config, + EGLNativeWindowType window, + const AttributeMap &attribs, + bool robustResourceInit); + ~WindowSurface() override; +}; + +class PbufferSurface final : public Surface +{ + public: + PbufferSurface(rx::EGLImplFactory *implFactory, + const Config *config, + const AttributeMap &attribs, + bool robustResourceInit); + PbufferSurface(rx::EGLImplFactory *implFactory, + 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, + 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_ |