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 <EGL/egl.h> 15 16 #include "common/PackedEnums.h" 17 #include "common/angleutils.h" 18 #include "libANGLE/AttributeMap.h" 19 #include "libANGLE/Debug.h" 20 #include "libANGLE/Error.h" 21 #include "libANGLE/FramebufferAttachment.h" 22 #include "libANGLE/RefCountObject.h" 23 #include "libANGLE/formatutils.h" 24 #include "libANGLE/renderer/SurfaceImpl.h" 25 26 namespace gl 27 { 28 class Context; 29 class Framebuffer; 30 class Texture; 31 } // namespace gl 32 33 namespace rx 34 { 35 class EGLImplFactory; 36 } 37 38 namespace egl 39 { 40 class Display; 41 struct Config; 42 43 using SupportedCompositorTiming = angle::PackedEnumBitSet<CompositorTiming>; 44 using SupportedTimestamps = angle::PackedEnumBitSet<Timestamp>; 45 46 struct SurfaceState final : private angle::NonCopyable 47 { 48 SurfaceState(const egl::Config *configIn, const AttributeMap &attributesIn); 49 ~SurfaceState(); 50 51 bool isRobustResourceInitEnabled() const; 52 bool hasProtectedContent() const; 53 EGLint getPreferredSwapInterval() const; 54 55 EGLLabelKHR label; 56 const egl::Config *config; 57 AttributeMap attributes; 58 59 bool timestampsEnabled; 60 SupportedCompositorTiming supportedCompositorTimings; 61 SupportedTimestamps supportedTimestamps; 62 bool directComposition; 63 EGLenum swapBehavior; 64 }; 65 66 class Surface : public LabeledObject, public gl::FramebufferAttachmentObject 67 { 68 public: getImplementation()69 rx::SurfaceImpl *getImplementation() const { return mImplementation; } 70 71 void setLabel(EGLLabelKHR label) override; 72 EGLLabelKHR getLabel() const override; 73 74 EGLint getType() const; 75 76 Error initialize(const Display *display); 77 Error makeCurrent(const gl::Context *context); 78 Error unMakeCurrent(const gl::Context *context); 79 Error prepareSwap(const gl::Context *context); 80 Error swap(const gl::Context *context); 81 Error swapWithDamage(const gl::Context *context, const EGLint *rects, EGLint n_rects); 82 Error swapWithFrameToken(const gl::Context *context, EGLFrameTokenANGLE frameToken); 83 Error postSubBuffer(const gl::Context *context, 84 EGLint x, 85 EGLint y, 86 EGLint width, 87 EGLint height); 88 Error setPresentationTime(EGLnsecsANDROID time); 89 Error querySurfacePointerANGLE(EGLint attribute, void **value); 90 Error bindTexImage(gl::Context *context, gl::Texture *texture, EGLint buffer); 91 Error releaseTexImage(const gl::Context *context, EGLint buffer); 92 93 Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc); 94 Error getMscRate(EGLint *numerator, EGLint *denominator); 95 96 EGLint isPostSubBufferSupported() const; 97 98 void setSwapInterval(EGLint interval); 99 Error onDestroy(const Display *display); 100 101 void setMipmapLevel(EGLint level); 102 void setMultisampleResolve(EGLenum resolve); 103 void setSwapBehavior(EGLenum behavior); 104 105 void setFixedWidth(EGLint width); 106 void setFixedHeight(EGLint height); 107 108 gl::Framebuffer *createDefaultFramebuffer(const gl::Context *context, 109 egl::Surface *readSurface); 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; isCurrentOnAnyContext()155 bool isCurrentOnAnyContext() const { return mIsCurrentOnAnyContext; } 156 getBoundTexture()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 onAttach(const gl::Context * context,rx::Serial framebufferSerial)170 void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override {} onDetach(const gl::Context * context,rx::Serial framebufferSerial)171 void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override {} 172 GLuint getId() const override; 173 getOrientation()174 EGLint getOrientation() const { return mOrientation; } 175 directComposition()176 bool directComposition() const { return mState.directComposition; } 177 178 gl::InitState initState(const gl::ImageIndex &imageIndex) const override; 179 void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override; 180 isRobustResourceInitEnabled()181 bool isRobustResourceInitEnabled() const { return mRobustResourceInitialization; } 182 getBindTexImageFormat()183 const gl::Format &getBindTexImageFormat() const { return mColorFormat; } 184 185 // EGL_ANDROID_get_frame_timestamps entry points 186 void setTimestampsEnabled(bool enabled); 187 bool isTimestampsEnabled() const; 188 189 const SupportedCompositorTiming &getSupportedCompositorTimings() const; 190 Error getCompositorTiming(EGLint numTimestamps, 191 const EGLint *names, 192 EGLnsecsANDROID *values) const; 193 194 Error getNextFrameId(EGLuint64KHR *frameId) const; 195 const SupportedTimestamps &getSupportedTimestamps() const; 196 Error getFrameTimestamps(EGLuint64KHR frameId, 197 EGLint numTimestamps, 198 const EGLint *timestamps, 199 EGLnsecsANDROID *values) const; 200 201 // Returns the offset into the texture backing the surface if specified via texture offset 202 // attributes (see EGL_ANGLE_d3d_texture_client_buffer extension). Returns zero offset 203 // otherwise. getTextureOffset()204 const gl::Offset &getTextureOffset() const { return mTextureOffset; } 205 206 Error getBufferAge(const gl::Context *context, EGLint *age); 207 208 Error setRenderBuffer(EGLint renderBuffer); 209 bufferAgeQueriedSinceLastSwap()210 bool bufferAgeQueriedSinceLastSwap() const { return mBufferAgeQueriedSinceLastSwap; } 211 void setDamageRegion(const EGLint *rects, EGLint n_rects); isDamageRegionSet()212 bool isDamageRegionSet() const { return mIsDamageRegionSet; } 213 addRef()214 void addRef() { mRefCount++; } release()215 void release() 216 { 217 ASSERT(mRefCount > 0); 218 mRefCount--; 219 } 220 221 protected: 222 Surface(EGLint surfaceType, 223 const egl::Config *config, 224 const AttributeMap &attributes, 225 bool forceRobustResourceInit, 226 EGLenum buftype = EGL_NONE); 227 ~Surface() override; 228 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 229 230 gl::Framebuffer *createDefaultFramebuffer(const Display *display); 231 232 // ANGLE-only method, used internally 233 friend class gl::Texture; 234 Error releaseTexImageFromTexture(const gl::Context *context); 235 236 SurfaceState mState; 237 rx::SurfaceImpl *mImplementation; 238 int mRefCount; 239 bool mDestroyed; 240 241 EGLint mType; 242 EGLenum mBuftype; 243 244 bool mPostSubBufferRequested; 245 246 bool mLargestPbuffer; 247 EGLenum mGLColorspace; 248 EGLenum mVGAlphaFormat; 249 EGLenum mVGColorspace; 250 bool mMipmapTexture; 251 EGLint mMipmapLevel; 252 EGLint mHorizontalResolution; 253 EGLint mVerticalResolution; 254 EGLenum mMultisampleResolve; 255 256 bool mFixedSize; 257 size_t mFixedWidth; 258 size_t mFixedHeight; 259 260 bool mRobustResourceInitialization; 261 262 TextureFormat mTextureFormat; 263 EGLenum mTextureTarget; 264 265 EGLint mPixelAspectRatio; // Display aspect ratio 266 EGLenum mRenderBuffer; // Render buffer 267 268 EGLint mOrientation; 269 270 // We don't use a binding pointer here. We don't ever want to own an orphaned texture. If a 271 // Texture is deleted the Surface is unbound in onDestroy. 272 gl::Texture *mTexture; 273 274 gl::Format mColorFormat; 275 gl::Format mDSFormat; 276 277 gl::Offset mTextureOffset; 278 279 bool mIsCurrentOnAnyContext; // The surface is current to a context/client API 280 uint8_t *mLockBufferPtr; // Memory owned by backend. 281 EGLint mLockBufferPitch; 282 283 bool mBufferAgeQueriedSinceLastSwap; 284 bool mIsDamageRegionSet; 285 286 private: 287 Error getBufferAgeImpl(const gl::Context *context, EGLint *age) const; 288 289 Error destroyImpl(const Display *display); 290 291 void postSwap(const gl::Context *context); 292 Error releaseRef(const Display *display); 293 294 // ObserverInterface implementation. 295 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 296 297 gl::InitState mInitState; 298 angle::ObserverBinding mImplObserverBinding; 299 }; 300 301 class WindowSurface final : public Surface 302 { 303 public: 304 WindowSurface(rx::EGLImplFactory *implFactory, 305 const Config *config, 306 EGLNativeWindowType window, 307 const AttributeMap &attribs, 308 bool robustResourceInit); 309 ~WindowSurface() override; 310 }; 311 312 class PbufferSurface final : public Surface 313 { 314 public: 315 PbufferSurface(rx::EGLImplFactory *implFactory, 316 const Config *config, 317 const AttributeMap &attribs, 318 bool robustResourceInit); 319 PbufferSurface(rx::EGLImplFactory *implFactory, 320 const Config *config, 321 EGLenum buftype, 322 EGLClientBuffer clientBuffer, 323 const AttributeMap &attribs, 324 bool robustResourceInit); 325 326 protected: 327 ~PbufferSurface() override; 328 }; 329 330 class PixmapSurface final : public Surface 331 { 332 public: 333 PixmapSurface(rx::EGLImplFactory *implFactory, 334 const Config *config, 335 NativePixmapType nativePixmap, 336 const AttributeMap &attribs, 337 bool robustResourceInit); 338 339 protected: 340 ~PixmapSurface() override; 341 }; 342 343 class ANGLE_NO_DISCARD ScopedSurfaceRef 344 { 345 public: ScopedSurfaceRef(Surface * surface)346 ScopedSurfaceRef(Surface *surface) : mSurface(surface) 347 { 348 if (mSurface) 349 { 350 mSurface->addRef(); 351 } 352 } ~ScopedSurfaceRef()353 ~ScopedSurfaceRef() 354 { 355 if (mSurface) 356 { 357 mSurface->release(); 358 } 359 } 360 361 private: 362 Surface *const mSurface; 363 }; 364 365 class SurfaceDeleter final 366 { 367 public: 368 SurfaceDeleter(const Display *display); 369 ~SurfaceDeleter(); 370 void operator()(Surface *surface); 371 372 private: 373 const Display *mDisplay; 374 }; 375 376 using SurfacePointer = angle::UniqueObjectPointerBase<Surface, SurfaceDeleter>; 377 378 } // namespace egl 379 380 #endif // LIBANGLE_SURFACE_H_ 381