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