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