1 // 2 // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // Surface.h: Defines the egl::Surface class, representing a drawing surface 8 // such as the client area of a window, including any back buffers. 9 // Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3. 10 11 #ifndef LIBANGLE_SURFACE_H_ 12 #define LIBANGLE_SURFACE_H_ 13 14 #include <memory> 15 16 #include <EGL/egl.h> 17 18 #include "common/PackedEnums.h" 19 #include "common/angleutils.h" 20 #include "libANGLE/AttributeMap.h" 21 #include "libANGLE/Debug.h" 22 #include "libANGLE/Error.h" 23 #include "libANGLE/FramebufferAttachment.h" 24 #include "libANGLE/RefCountObject.h" 25 #include "libANGLE/formatutils.h" 26 #include "libANGLE/renderer/SurfaceImpl.h" 27 28 namespace gl 29 { 30 class Context; 31 class Framebuffer; 32 class Texture; 33 } // namespace gl 34 35 namespace rx 36 { 37 class EGLImplFactory; 38 } 39 40 namespace egl 41 { 42 class Display; 43 struct Config; 44 45 using SupportedCompositorTiming = angle::PackedEnumBitSet<CompositorTiming>; 46 using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>; 47 48 struct SurfaceState final : private angle::NonCopyable 49 { 50 SurfaceState(SurfaceID idIn, const egl::Config *configIn, const AttributeMap &attributesIn); 51 ~SurfaceState(); 52 53 bool isRobustResourceInitEnabled() const; 54 bool hasProtectedContent() const; 55 56 SurfaceID id; 57 58 EGLLabelKHR label; 59 const egl::Config *config; 60 AttributeMap attributes; 61 62 bool timestampsEnabled; 63 bool autoRefreshEnabled; 64 SupportedCompositorTiming supportedCompositorTimings; 65 SupportedTimestamps supportedTimestamps; 66 bool directComposition; 67 EGLenum swapBehavior; 68 EGLint swapInterval; 69 }; 70 71 class Surface : public LabeledObject, public gl::FramebufferAttachmentObject 72 { 73 public: getImplementation()74 rx::SurfaceImpl *getImplementation() const { return mImplementation; } 75 76 void setLabel(EGLLabelKHR label) override; 77 EGLLabelKHR getLabel() const override; 78 79 EGLint getType() const; 80 81 Error initialize(const Display *display); 82 Error makeCurrent(const gl::Context *context); 83 Error unMakeCurrent(const gl::Context *context); 84 Error prepareSwap(const gl::Context *context); 85 Error swap(gl::Context *context); 86 Error swapWithDamage(gl::Context *context, const EGLint *rects, EGLint n_rects); 87 Error postSubBuffer(const gl::Context *context, 88 EGLint x, 89 EGLint y, 90 EGLint width, 91 EGLint height); 92 Error setPresentationTime(EGLnsecsANDROID time); 93 Error querySurfacePointerANGLE(EGLint attribute, void **value); 94 Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer); 95 Error releaseTexImage(const gl::Context *context, EGLint buffer); 96 97 Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc); 98 Error getMscRate(EGLint *numerator, EGLint *denominator); 99 100 EGLint isPostSubBufferSupported() const; 101 102 void setRequestedSwapInterval(EGLint interval); 103 void setSwapInterval(const Display *display, EGLint interval); 104 Error onDestroy(const Display *display); 105 106 void setMipmapLevel(EGLint level); 107 void setMultisampleResolve(EGLenum resolve); 108 void setSwapBehavior(EGLenum behavior); 109 110 void setFixedWidth(EGLint width); 111 void setFixedHeight(EGLint height); 112 113 const Config *getConfig() const; 114 115 // width and height can change with client window resizing 116 EGLint getWidth() const; 117 EGLint getHeight() const; 118 // Note: windows cannot be resized on Android. The approach requires 119 // calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR. However, that is 120 // expensive; and there are troublesome timing issues for other parts of 121 // ANGLE (which cause test failures and crashes). Therefore, a 122 // special-Android-only path is created just for the querying of EGL_WIDTH 123 // and EGL_HEIGHT. 124 // https://issuetracker.google.com/issues/153329980 125 egl::Error getUserWidth(const egl::Display *display, EGLint *value) const; 126 egl::Error getUserHeight(const egl::Display *display, EGLint *value) const; 127 EGLint getPixelAspectRatio() const; 128 EGLenum getRenderBuffer() const; 129 EGLenum getRequestedRenderBuffer() const; 130 EGLenum getSwapBehavior() const; 131 TextureFormat getTextureFormat() const; 132 EGLenum getTextureTarget() const; 133 bool getLargestPbuffer() const; 134 EGLenum getGLColorspace() const; 135 EGLenum getVGAlphaFormat() const; 136 EGLenum getVGColorspace() const; 137 bool getMipmapTexture() const; 138 EGLint getMipmapLevel() const; 139 EGLint getHorizontalResolution() const; 140 EGLint getVerticalResolution() const; 141 EGLenum getMultisampleResolve() const; 142 bool hasProtectedContent() const override; hasFoveatedRendering()143 bool hasFoveatedRendering() const override { return false; } getFoveationState()144 const gl::FoveationState *getFoveationState() const override { return nullptr; } 145 146 // For lock surface buffer 147 EGLint getBitmapPitch() const; 148 EGLint getBitmapOrigin() const; 149 EGLint getRedOffset() const; 150 EGLint getGreenOffset() const; 151 EGLint getBlueOffset() const; 152 EGLint getAlphaOffset() const; 153 EGLint getLuminanceOffset() const; 154 EGLint getBitmapPixelSize() const; 155 EGLAttribKHR getBitmapPointer() const; 156 EGLint getCompressionRate(const egl::Display *display) const; 157 egl::Error lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes); 158 egl::Error unlockSurfaceKHR(const egl::Display *display); 159 160 bool isLocked() const; isCurrentOnAnyContext()161 bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; } 162 getBoundTexture()163 gl::Texture *getBoundTexture() const { return mTexture; } 164 165 EGLint isFixedSize() const; 166 167 // FramebufferAttachmentObject implementation 168 bool isAttachmentSpecified(const gl::ImageIndex &imageIndex) const override; 169 gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; 170 gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override; 171 GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; 172 bool isRenderable(const gl::Context *context, 173 GLenum binding, 174 const gl::ImageIndex &imageIndex) const override; 175 bool isYUV() const override; 176 bool isExternalImageWithoutIndividualSync() const override; 177 bool hasFrontBufferUsage() const override; 178 onAttach(const gl::Context * context,rx::UniqueSerial framebufferSerial)179 void onAttach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {} onDetach(const gl::Context * context,rx::UniqueSerial framebufferSerial)180 void onDetach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {} id()181 SurfaceID id() const { return mState.id; } 182 GLuint getId() const override; 183 getOrientation()184 EGLint getOrientation() const { return mOrientation; } 185 directComposition()186 bool directComposition() const { return mState.directComposition; } 187 188 gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override; 189 void setInitState(GLenum binding, 190 const gl::ImageIndex &imageIndex, 191 gl::InitState initState) override; 192 isRobustResourceInitEnabled()193 bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; } 194 getBindTexImageFormat()195 const gl::Format &getBindTexImageFormat() const { return mColorFormat; } 196 197 // EGL_ANDROID_get_frame_timestamps entry points 198 void setTimestampsEnabled(bool enabled); 199 bool isTimestampsEnabled() const; 200 201 // EGL_ANDROID_front_buffer_auto_refresh entry points 202 Error setAutoRefreshEnabled(bool enabled); 203 204 const SupportedCompositorTiming &getSupportedCompositorTimings() const; 205 Error getCompositorTiming(EGLint numTimestamps, 206 const EGLint *names, 207 EGLnsecsANDROID *values) const; 208 209 Error getNextFrameId(EGLuint64KHR *frameId) const; 210 const SupportedTimestamps &getSupportedTimestamps() const; 211 Error getFrameTimestamps(EGLuint64KHR frameId, 212 EGLint numTimestamps, 213 const EGLint *timestamps, 214 EGLnsecsANDROID *values) const; 215 216 // Returns the offset into the texture backing the surface if specified via texture offset 217 // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset 218 // otherwise. getTextureOffset()219 const gl::Offset &getTextureOffset() const { return mTextureOffset; } 220 221 Error getBufferAge(const gl::Context *context, EGLint *age); 222 223 Error setRenderBuffer(EGLint renderBuffer); 224 void setRequestedRenderBuffer(EGLint requestedRenderBuffer); 225 bufferAgeQueriedSinceLastSwap()226 bool bufferAgeQueriedSinceLastSwap() const { return mBufferAgeQueriedSinceLastSwap; } 227 void setDamageRegion(const EGLint *rects, EGLint n_rects); isDamageRegionSet()228 bool isDamageRegionSet() const { return mIsDamageRegionSet; } 229 addRef()230 void addRef() { mRefCount++; } release()231 void release() 232 { 233 ASSERT(mRefCount > 0); 234 mRefCount--; 235 } isReferenced()236 bool isReferenced() const { return mRefCount > 0; } 237 238 protected: 239 Surface(EGLint surfaceType, 240 SurfaceID id, 241 const egl::Config *config, 242 const AttributeMap &attributes, 243 bool forceRobustResourceInit, 244 EGLenum buftype = EGL_NONE); 245 ~Surface() override; 246 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 247 248 // ANGLE-only method, used internally 249 friend class gl::Texture; 250 Error releaseTexImageFromTexture(const gl::Context *context); 251 252 SurfaceState mState; 253 rx::SurfaceImpl *mImplementation; 254 int mRefCount; 255 bool mDestroyed; 256 257 EGLint mType; 258 EGLenum mBuftype; 259 260 bool mPostSubBufferRequested; 261 262 bool mLargestPbuffer; 263 EGLenum mGLColorspace; 264 EGLenum mVGAlphaFormat; 265 EGLenum mVGColorspace; 266 bool mMipmapTexture; 267 EGLint mMipmapLevel; 268 EGLint mHorizontalResolution; 269 EGLint mVerticalResolution; 270 EGLenum mMultisampleResolve; 271 272 bool mFixedSize; 273 size_t mFixedWidth; 274 size_t mFixedHeight; 275 276 bool mRobustResourceInitialization; 277 278 TextureFormat mTextureFormat; 279 EGLenum mTextureTarget; 280 281 EGLint mPixelAspectRatio; // Display aspect ratio 282 EGLenum mRenderBuffer; // Render buffer 283 EGLenum mRequestedRenderBuffer; // Requested render buffer 284 285 EGLint mRequestedSwapInterval; 286 287 EGLint mOrientation; 288 289 // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a 290 // Texture is deleted the Surface is unbound in onDestroy. 291 gl::Texture *mTexture; 292 293 gl::Format mColorFormat; 294 gl::Format mDSFormat; 295 296 gl::Offset mTextureOffset; 297 298 bool mIsCurrentOnAnyContext; // The surface is current to a context/client API 299 uint8_t *mLockBufferPtr; // Memory owned by backend. 300 EGLint mLockBufferPitch; 301 302 bool mBufferAgeQueriedSinceLastSwap; 303 bool mIsDamageRegionSet; 304 305 private: 306 Error getBufferAgeImpl(const gl::Context *context, EGLint *age) const; 307 308 Error destroyImpl(const Display *display); 309 310 void postSwap(const gl::Context *context); 311 Error releaseRef(const Display *display); 312 313 // ObserverInterface implementation. 314 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 315 316 Error updatePropertiesOnSwap(const gl::Context *context); 317 318 gl::InitState mColorInitState; 319 gl::InitState mDepthStencilInitState; 320 angle::ObserverBinding mImplObserverBinding; 321 }; 322 323 class WindowSurface final : public Surface 324 { 325 public: 326 WindowSurface(rx::EGLImplFactory *implFactory, 327 SurfaceID id, 328 const Config *config, 329 EGLNativeWindowType window, 330 const AttributeMap &attribs, 331 bool robustResourceInit); 332 ~WindowSurface() override; 333 }; 334 335 class PbufferSurface final : public Surface 336 { 337 public: 338 PbufferSurface(rx::EGLImplFactory *implFactory, 339 SurfaceID id, 340 const Config *config, 341 const AttributeMap &attribs, 342 bool robustResourceInit); 343 PbufferSurface(rx::EGLImplFactory *implFactory, 344 SurfaceID id, 345 const Config *config, 346 EGLenum buftype, 347 EGLClientBuffer clientBuffer, 348 const AttributeMap &attribs, 349 bool robustResourceInit); 350 351 protected: 352 ~PbufferSurface() override; 353 }; 354 355 class PixmapSurface final : public Surface 356 { 357 public: 358 PixmapSurface(rx::EGLImplFactory *implFactory, 359 SurfaceID id, 360 const Config *config, 361 NativePixmapType nativePixmap, 362 const AttributeMap &attribs, 363 bool robustResourceInit); 364 365 protected: 366 ~PixmapSurface() override; 367 }; 368 369 class [[nodiscard]] ScopedSurfaceRef 370 { 371 public: ScopedSurfaceRef(Surface * surface)372 ScopedSurfaceRef(Surface *surface) : mSurface(surface) 373 { 374 if (mSurface) 375 { 376 mSurface->addRef(); 377 } 378 } ~ScopedSurfaceRef()379 ~ScopedSurfaceRef() 380 { 381 if (mSurface) 382 { 383 mSurface->release(); 384 } 385 } 386 387 private: 388 Surface *const mSurface; 389 }; 390 391 class SurfaceDeleter final 392 { 393 public: 394 SurfaceDeleter(const Display *display); 395 ~SurfaceDeleter(); 396 void operator()(Surface *surface); 397 398 private: 399 const Display *mDisplay; 400 }; 401 402 using SurfacePointer = std::unique_ptr<Surface, SurfaceDeleter>; 403 404 } // namespace egl 405 406 #endif // LIBANGLE_SURFACE_H_ 407