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/angleutils.h" 13 #include "libANGLE/AttributeMap.h" 14 #include "libANGLE/Debug.h" 15 #include "libANGLE/Error.h" 16 #include "libANGLE/FramebufferAttachment.h" 17 #include "libANGLE/RefCountObject.h" 18 #include "libANGLE/formatutils.h" 19 20 #include <set> 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 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 hasProtectedContent() const override; 56 57 protected: 58 // Set the image target of this sibling 59 void setTargetImage(const gl::Context *context, egl::Image *imageTarget); 60 61 // Orphan all EGL image sources and targets 62 angle::Result orphanImages(const gl::Context *context, 63 RefCountObjectReleaser<Image> *outReleaseImage); 64 65 void notifySiblings(angle::SubjectMessage message); 66 67 private: 68 friend class Image; 69 70 // Called from Image only to add a new source image 71 void addImageSource(egl::Image *imageSource); 72 73 // Called from Image only to remove a source image when the Image is being deleted 74 void removeImageSource(egl::Image *imageSource); 75 76 std::set<Image *> mSourcesOf; 77 BindingPointer<Image> mTargetOf; 78 }; 79 80 // Wrapper for EGLImage sources that are not owned by ANGLE, these often have to do 81 // platform-specific queries for format and size information. 82 class ExternalImageSibling : public ImageSibling 83 { 84 public: 85 ExternalImageSibling(rx::EGLImplFactory *factory, 86 const gl::Context *context, 87 EGLenum target, 88 EGLClientBuffer buffer, 89 const AttributeMap &attribs); 90 ~ExternalImageSibling() override; 91 92 void onDestroy(const egl::Display *display); 93 94 Error initialize(const Display *display); 95 96 gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; 97 gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override; 98 GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; 99 GLuint getLevelCount() const; 100 bool isRenderable(const gl::Context *context, 101 GLenum binding, 102 const gl::ImageIndex &imageIndex) const override; 103 bool isTextureable(const gl::Context *context) const; 104 bool isYUV() const override; 105 bool isCubeMap() const; 106 bool hasProtectedContent() const override; 107 108 void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override; 109 void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override; 110 GLuint getId() const override; 111 112 gl::InitState initState(const gl::ImageIndex &imageIndex) const override; 113 void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override; 114 115 rx::ExternalImageSiblingImpl *getImplementation() const; 116 117 protected: 118 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 119 120 private: 121 // ObserverInterface implementation. 122 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 123 124 std::unique_ptr<rx::ExternalImageSiblingImpl> mImplementation; 125 angle::ObserverBinding mImplObserverBinding; 126 }; 127 128 struct ImageState : private angle::NonCopyable 129 { 130 ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); 131 ~ImageState(); 132 133 EGLLabelKHR label; 134 EGLenum target; 135 gl::ImageIndex imageIndex; 136 ImageSibling *source; 137 std::set<ImageSibling *> targets; 138 139 gl::Format format; 140 bool yuv; 141 bool cubeMap; 142 gl::Extents size; 143 size_t samples; 144 GLuint levelCount; 145 EGLenum sourceType; 146 EGLenum colorspace; 147 bool hasProtectedContent; 148 }; 149 150 class Image final : public RefCountObject, public LabeledObject 151 { 152 public: 153 Image(rx::EGLImplFactory *factory, 154 const gl::Context *context, 155 EGLenum target, 156 ImageSibling *buffer, 157 const AttributeMap &attribs); 158 159 void onDestroy(const Display *display) override; 160 ~Image() override; 161 162 void setLabel(EGLLabelKHR label) override; 163 EGLLabelKHR getLabel() const override; 164 165 const gl::Format &getFormat() const; 166 bool isRenderable(const gl::Context *context) const; 167 bool isTexturable(const gl::Context *context) const; 168 bool isYUV() const; 169 // Returns true only if the eglImage contains a complete cubemap 170 bool isCubeMap() const; 171 size_t getWidth() const; 172 size_t getHeight() const; 173 const gl::Extents &getExtents() const; 174 bool isLayered() const; 175 size_t getSamples() const; 176 GLuint getLevelCount() const; 177 bool hasProtectedContent() const; 178 179 Error initialize(const Display *display); 180 181 rx::ImageImpl *getImplementation() const; 182 183 bool orphaned() const; 184 gl::InitState sourceInitState() const; 185 void setInitState(gl::InitState initState); 186 187 Error exportVkImage(void *vkImage, void *vkImageCreateInfo); 188 189 private: 190 friend class ImageSibling; 191 192 // Called from ImageSibling only notify the image that a new target sibling exists for state 193 // tracking. 194 void addTargetSibling(ImageSibling *sibling); 195 196 // Called from ImageSibling only to notify the image that a sibling (source or target) has 197 // been respecified and state tracking should be updated. 198 angle::Result orphanSibling(const gl::Context *context, ImageSibling *sibling); 199 200 void notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message); 201 202 ImageState mState; 203 rx::ImageImpl *mImplementation; 204 bool mOrphanedAndNeedsInit; 205 }; 206 } // namespace egl 207 208 #endif // LIBANGLE_IMAGE_H_ 209