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