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 EGLint getPreferredSwapInterval() const; 56 57 SurfaceID id; 58 59 EGLLabelKHR label; 60 const egl::Config *config; 61 AttributeMap attributes; 62 63 bool timestampsEnabled; 64 bool autoRefreshEnabled; 65 SupportedCompositorTiming supportedCompositorTimings; 66 SupportedTimestamps supportedTimestamps; 67 bool directComposition; 68 EGLenum swapBehavior; 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 swapWithFrameToken(gl::Context *context, EGLFrameTokenANGLE frameToken); 88 Error postSubBuffer(const gl::Context *context, 89 EGLint x, 90 EGLint y, 91 EGLint width, 92 EGLint height); 93 Error setPresentationTime(EGLnsecsANDROID time); 94 Error querySurfacePointerANGLE(EGLint attribute, void **value); 95 Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer); 96 Error releaseTexImage(const gl::Context *context, EGLint buffer); 97 98 Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc); 99 Error getMscRate(EGLint *numerator, EGLint *denominator); 100 101 EGLint isPostSubBufferSupported() const; 102 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 getSwapBehavior() const; 130 TextureFormat getTextureFormat() const; 131 EGLenum getTextureTarget() const; 132 bool getLargestPbuffer() const; 133 EGLenum getGLColorspace() const; 134 EGLenum getVGAlphaFormat() const; 135 EGLenum getVGColorspace() const; 136 bool getMipmapTexture() const; 137 EGLint getMipmapLevel() const; 138 EGLint getHorizontalResolution() const; 139 EGLint getVerticalResolution() const; 140 EGLenum getMultisampleResolve() const; 141 bool hasProtectedContent() const override; hasFoveatedRendering()142 bool hasFoveatedRendering() const override { return false; } getFoveationState()143 const gl::FoveationState *getFoveationState() const override { return nullptr; } 144 145 // For lock surface buffer 146 EGLint getBitmapPitch() const; 147 EGLint getBitmapOrigin() const; 148 EGLint getRedOffset() const; 149 EGLint getGreenOffset() const; 150 EGLint getBlueOffset() const; 151 EGLint getAlphaOffset() const; 152 EGLint getLuminanceOffset() const; 153 EGLint getBitmapPixelSize() const; 154 EGLAttribKHR getBitmapPointer() const; 155 egl::Error lockSurfaceKHR(const egl::Display *display, const AttributeMap &attributes); 156 egl::Error unlockSurfaceKHR(const egl::Display *display); 157 158 bool isLocked() const; isCurrentOnAnyContext()159 bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; } 160 getBoundTexture()161 gl::Texture *getBoundTexture() const { return mTexture; } 162 163 EGLint isFixedSize() const; 164 165 // FramebufferAttachmentObject implementation 166 gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; 167 gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override; 168 GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; 169 bool isRenderable(const gl::Context *context, 170 GLenum binding, 171 const gl::ImageIndex &imageIndex) const override; 172 bool isYUV() const override; 173 bool isExternalImageWithoutIndividualSync() const override; 174 bool hasFrontBufferUsage() const override; 175 onAttach(const gl::Context * context,rx::UniqueSerial framebufferSerial)176 void onAttach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {} onDetach(const gl::Context * context,rx::UniqueSerial framebufferSerial)177 void onDetach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override {} id()178 SurfaceID id() const { return mState.id; } 179 GLuint getId() const override; 180 getOrientation()181 EGLint getOrientation() const { return mOrientation; } 182 directComposition()183 bool directComposition() const { return mState.directComposition; } 184 185 gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override; 186 void setInitState(GLenum binding, 187 const gl::ImageIndex &imageIndex, 188 gl::InitState initState) override; 189 isRobustResourceInitEnabled()190 bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; } 191 getBindTexImageFormat()192 const gl::Format &getBindTexImageFormat() const { return mColorFormat; } 193 194 // EGL_ANDROID_get_frame_timestamps entry points 195 void setTimestampsEnabled(bool enabled); 196 bool isTimestampsEnabled() const; 197 198 // EGL_ANDROID_front_buffer_auto_refresh entry points 199 Error setAutoRefreshEnabled(bool enabled); 200 201 const SupportedCompositorTiming &getSupportedCompositorTimings() const; 202 Error getCompositorTiming(EGLint numTimestamps, 203 const EGLint *names, 204 EGLnsecsANDROID *values) const; 205 206 Error getNextFrameId(EGLuint64KHR *frameId) const; 207 const SupportedTimestamps &getSupportedTimestamps() const; 208 Error getFrameTimestamps(EGLuint64KHR frameId, 209 EGLint numTimestamps, 210 const EGLint *timestamps, 211 EGLnsecsANDROID *values) const; 212 213 // Returns the offset into the texture backing the surface if specified via texture offset 214 // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset 215 // otherwise. getTextureOffset()216 const gl::Offset &getTextureOffset() const { return mTextureOffset; } 217 218 Error getBufferAge(const gl::Context *context, EGLint *age); 219 220 Error setRenderBuffer(EGLint renderBuffer); 221 bufferAgeQueriedSinceLastSwap()222 bool bufferAgeQueriedSinceLastSwap() const { return mBufferAgeQueriedSinceLastSwap; } 223 void setDamageRegion(const EGLint *rects, EGLint n_rects); isDamageRegionSet()224 bool isDamageRegionSet() const { return mIsDamageRegionSet; } 225 addRef()226 void addRef() { mRefCount++; } release()227 void release() 228 { 229 ASSERT(mRefCount > 0); 230 mRefCount--; 231 } isReferenced()232 bool isReferenced() const { return mRefCount > 0; } 233 234 protected: 235 Surface(EGLint surfaceType, 236 SurfaceID id, 237 const egl::Config *config, 238 const AttributeMap &attributes, 239 bool forceRobustResourceInit, 240 EGLenum buftype = EGL_NONE); 241 ~Surface() override; 242 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 243 244 // ANGLE-only method, used internally 245 friend class gl::Texture; 246 Error releaseTexImageFromTexture(const gl::Context *context); 247 248 SurfaceState mState; 249 rx::SurfaceImpl *mImplementation; 250 int mRefCount; 251 bool mDestroyed; 252 253 EGLint mType; 254 EGLenum mBuftype; 255 256 bool mPostSubBufferRequested; 257 258 bool mLargestPbuffer; 259 EGLenum mGLColorspace; 260 EGLenum mVGAlphaFormat; 261 EGLenum mVGColorspace; 262 bool mMipmapTexture; 263 EGLint mMipmapLevel; 264 EGLint mHorizontalResolution; 265 EGLint mVerticalResolution; 266 EGLenum mMultisampleResolve; 267 268 bool mFixedSize; 269 size_t mFixedWidth; 270 size_t mFixedHeight; 271 272 bool mRobustResourceInitialization; 273 274 TextureFormat mTextureFormat; 275 EGLenum mTextureTarget; 276 277 EGLint mPixelAspectRatio; // Display aspect ratio 278 EGLenum mRenderBuffer; // Render buffer 279 280 EGLint mOrientation; 281 282 // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a 283 // Texture is deleted the Surface is unbound in onDestroy. 284 gl::Texture *mTexture; 285 286 gl::Format mColorFormat; 287 gl::Format mDSFormat; 288 289 gl::Offset mTextureOffset; 290 291 bool mIsCurrentOnAnyContext; // The surface is current to a context/client API 292 uint8_t *mLockBufferPtr; // Memory owned by backend. 293 EGLint mLockBufferPitch; 294 295 bool mBufferAgeQueriedSinceLastSwap; 296 bool mIsDamageRegionSet; 297 298 private: 299 Error getBufferAgeImpl(const gl::Context *context, EGLint *age) const; 300 301 Error destroyImpl(const Display *display); 302 303 void postSwap(const gl::Context *context); 304 Error releaseRef(const Display *display); 305 306 // ObserverInterface implementation. 307 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 308 309 gl::InitState mColorInitState; 310 gl::InitState mDepthStencilInitState; 311 angle::ObserverBinding mImplObserverBinding; 312 }; 313 314 class WindowSurface final : public Surface 315 { 316 public: 317 WindowSurface(rx::EGLImplFactory *implFactory, 318 SurfaceID id, 319 const Config *config, 320 EGLNativeWindowType window, 321 const AttributeMap &attribs, 322 bool robustResourceInit); 323 ~WindowSurface() override; 324 }; 325 326 class PbufferSurface final : public Surface 327 { 328 public: 329 PbufferSurface(rx::EGLImplFactory *implFactory, 330 SurfaceID id, 331 const Config *config, 332 const AttributeMap &attribs, 333 bool robustResourceInit); 334 PbufferSurface(rx::EGLImplFactory *implFactory, 335 SurfaceID id, 336 const Config *config, 337 EGLenum buftype, 338 EGLClientBuffer clientBuffer, 339 const AttributeMap &attribs, 340 bool robustResourceInit); 341 342 protected: 343 ~PbufferSurface() override; 344 }; 345 346 class PixmapSurface final : public Surface 347 { 348 public: 349 PixmapSurface(rx::EGLImplFactory *implFactory, 350 SurfaceID id, 351 const Config *config, 352 NativePixmapType nativePixmap, 353 const AttributeMap &attribs, 354 bool robustResourceInit); 355 356 protected: 357 ~PixmapSurface() override; 358 }; 359 360 class [[nodiscard]] ScopedSurfaceRef 361 { 362 public: ScopedSurfaceRef(Surface * surface)363 ScopedSurfaceRef(Surface *surface) : mSurface(surface) 364 { 365 if (mSurface) 366 { 367 mSurface->addRef(); 368 } 369 } ~ScopedSurfaceRef()370 ~ScopedSurfaceRef() 371 { 372 if (mSurface) 373 { 374 mSurface->release(); 375 } 376 } 377 378 private: 379 Surface *const mSurface; 380 }; 381 382 class SurfaceDeleter final 383 { 384 public: 385 SurfaceDeleter(const Display *display); 386 ~SurfaceDeleter(); 387 void operator()(Surface *surface); 388 389 private: 390 const Display *mDisplay; 391 }; 392 393 using SurfacePointer = std::unique_ptr<Surface, SurfaceDeleter>; 394 395 } // namespace egl 396 397 #endif // LIBANGLE_SURFACE_H_ 398