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