1 // 2 // Copyright 2015 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 // Image.h: Defines the egl::Image class representing the EGLimage object. 8 9 #ifndef LIBANGLE_IMAGE_H_ 10 #define LIBANGLE_IMAGE_H_ 11 12 #include "common/FastVector.h" 13 #include "common/SimpleMutex.h" 14 #include "common/angleutils.h" 15 #include "libANGLE/AttributeMap.h" 16 #include "libANGLE/Debug.h" 17 #include "libANGLE/Error.h" 18 #include "libANGLE/FramebufferAttachment.h" 19 #include "libANGLE/RefCountObject.h" 20 #include "libANGLE/formatutils.h" 21 22 namespace rx 23 { 24 class EGLImplFactory; 25 class ImageImpl; 26 class ExternalImageSiblingImpl; 27 28 // Used for distinguishing dirty bit messages from gl::Texture/rx::TexureImpl/gl::Image. 29 constexpr size_t kTextureImageImplObserverMessageIndex = 0; 30 constexpr size_t kTextureImageSiblingMessageIndex = 1; 31 } // namespace rx 32 33 namespace egl 34 { 35 class Image; 36 class Display; 37 class ContextMutex; 38 39 // Only currently Renderbuffers and Textures can be bound with images. This makes the relationship 40 // explicit, and also ensures that an image sibling can determine if it's been initialized or not, 41 // which is important for the robust resource init extension with Textures and EGLImages. 42 class ImageSibling : public gl::FramebufferAttachmentObject 43 { 44 public: 45 ImageSibling(); 46 ~ImageSibling() override; 47 48 bool isEGLImageTarget() const; 49 gl::InitState sourceEGLImageInitState() const; 50 void setSourceEGLImageInitState(gl::InitState initState) const; 51 52 bool isRenderable(const gl::Context *context, 53 GLenum binding, 54 const gl::ImageIndex &imageIndex) const override; 55 bool isYUV() const override; 56 bool isExternalImageWithoutIndividualSync() const override; 57 bool hasFrontBufferUsage() const override; 58 bool hasProtectedContent() const override; hasFoveatedRendering()59 bool hasFoveatedRendering() const override { return false; } getFoveationState()60 const gl::FoveationState *getFoveationState() const override { return nullptr; } 61 62 protected: 63 // Set the image target of this sibling 64 void setTargetImage(const gl::Context *context, egl::Image *imageTarget); 65 66 // Orphan all EGL image sources and targets 67 angle::Result orphanImages(const gl::Context *context, 68 RefCountObjectReleaser<Image> *outReleaseImage); 69 70 void notifySiblings(angle::SubjectMessage message); 71 72 private: 73 friend class Image; 74 75 // Called from Image only to add a new source image 76 void addImageSource(egl::Image *imageSource); 77 78 // Called from Image only to remove a source image when the Image is being deleted 79 void removeImageSource(egl::Image *imageSource); 80 81 static constexpr size_t kSourcesOfSetSize = 2; 82 angle::FlatUnorderedSet<Image *, kSourcesOfSetSize> mSourcesOf; 83 BindingPointer<Image> mTargetOf; 84 }; 85 86 // Wrapper for EGLImage sources that are not owned by ANGLE, these often have to do 87 // platform-specific queries for format and size information. 88 class ExternalImageSibling : public ImageSibling 89 { 90 public: 91 ExternalImageSibling(rx::EGLImplFactory *factory, 92 const gl::Context *context, 93 EGLenum target, 94 EGLClientBuffer buffer, 95 const AttributeMap &attribs); 96 ~ExternalImageSibling() override; 97 98 void onDestroy(const egl::Display *display); 99 100 Error initialize(const Display *display, const gl::Context *context); 101 102 gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; 103 gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override; 104 GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; 105 GLuint getLevelCount() const; 106 bool isRenderable(const gl::Context *context, 107 GLenum binding, 108 const gl::ImageIndex &imageIndex) const override; 109 bool isTextureable(const gl::Context *context) const; 110 bool isYUV() const override; 111 bool hasFrontBufferUsage() const override; 112 bool isCubeMap() const; 113 bool hasProtectedContent() const override; 114 115 void onAttach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override; 116 void onDetach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override; 117 GLuint getId() const override; 118 119 gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override; 120 void setInitState(GLenum binding, 121 const gl::ImageIndex &imageIndex, 122 gl::InitState initState) override; 123 124 rx::ExternalImageSiblingImpl *getImplementation() const; 125 126 protected: 127 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 128 129 private: 130 // ObserverInterface implementation. 131 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 132 133 std::unique_ptr<rx::ExternalImageSiblingImpl> mImplementation; 134 angle::ObserverBinding mImplObserverBinding; 135 }; 136 137 struct ImageState : private angle::NonCopyable 138 { 139 ImageState(ImageID id, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); 140 ~ImageState(); 141 142 ImageID id; 143 144 EGLLabelKHR label; 145 EGLenum target; 146 gl::ImageIndex imageIndex; 147 ImageSibling *source; 148 149 gl::Format format; 150 bool yuv; 151 bool cubeMap; 152 gl::Extents size; 153 size_t samples; 154 GLuint levelCount; 155 EGLenum colorspace; 156 bool hasProtectedContent; 157 158 mutable angle::SimpleMutex targetsLock; 159 160 static constexpr size_t kTargetsSetSize = 2; 161 angle::FlatUnorderedSet<ImageSibling *, kTargetsSetSize> targets; 162 }; 163 164 class Image final : public ThreadSafeRefCountObject, public LabeledObject 165 { 166 public: 167 Image(rx::EGLImplFactory *factory, 168 ImageID id, 169 const gl::Context *context, 170 EGLenum target, 171 ImageSibling *buffer, 172 const AttributeMap &attribs); 173 174 void onDestroy(const Display *display) override; 175 ~Image() override; 176 id()177 ImageID id() const { return mState.id; } 178 179 void setLabel(EGLLabelKHR label) override; 180 EGLLabelKHR getLabel() const override; 181 182 const gl::Format &getFormat() const; 183 bool isRenderable(const gl::Context *context) const; 184 bool isTexturable(const gl::Context *context) const; 185 bool isYUV() const; 186 bool isExternalImageWithoutIndividualSync() const; 187 bool hasFrontBufferUsage() const; 188 // Returns true only if the eglImage contains a complete cubemap 189 bool isCubeMap() const; 190 size_t getWidth() const; 191 size_t getHeight() const; 192 const gl::Extents &getExtents() const; 193 bool isLayered() const; 194 size_t getSamples() const; 195 GLuint getLevelCount() const; 196 bool hasProtectedContent() const; 197 bool isFixedRatedCompression(const gl::Context *context) const; getColorspaceAttribute()198 EGLenum getColorspaceAttribute() const { return mState.colorspace; } 199 200 Error initialize(const Display *display, const gl::Context *context); 201 202 rx::ImageImpl *getImplementation() const; 203 204 bool orphaned() const; 205 gl::InitState sourceInitState() const; 206 void setInitState(gl::InitState initState); 207 208 Error exportVkImage(void *vkImage, void *vkImageCreateInfo); 209 getContextMutex()210 ContextMutex *getContextMutex() const { return mContextMutex; } 211 212 private: 213 friend class ImageSibling; 214 215 // Called from ImageSibling only notify the image that a new target sibling exists for state 216 // tracking. 217 void addTargetSibling(ImageSibling *sibling); 218 219 // Called from ImageSibling only to notify the image that a sibling (source or target) has 220 // been respecified and state tracking should be updated. 221 angle::Result orphanSibling(const gl::Context *context, ImageSibling *sibling); 222 223 void notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message); 224 225 ImageState mState; 226 rx::ImageImpl *mImplementation; 227 bool mOrphanedAndNeedsInit; 228 bool mIsTexturable = false; 229 bool mIsRenderable = false; 230 231 ContextMutex *mContextMutex; // Reference counted 232 }; 233 } // namespace egl 234 235 #endif // LIBANGLE_IMAGE_H_ 236