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 isAttachmentSpecified(const gl::ImageIndex &imageIndex) const override; 53 bool isRenderable(const gl::Context *context, 54 GLenum binding, 55 const gl::ImageIndex &imageIndex) const override; 56 bool isYUV() const override; 57 bool isExternalImageWithoutIndividualSync() const override; 58 bool hasFrontBufferUsage() const override; 59 bool hasProtectedContent() const override; hasFoveatedRendering()60 bool hasFoveatedRendering() const override { return false; } getFoveationState()61 const gl::FoveationState *getFoveationState() const override { return nullptr; } 62 63 protected: 64 static constexpr size_t kSourcesOfSetSize = 2; 65 using UnorderedSetSiblingSource = angle::FlatUnorderedSet<Image *, kSourcesOfSetSize>; 66 getSiblingSourcesOf()67 const UnorderedSetSiblingSource &getSiblingSourcesOf() const { return mSourcesOf; } 68 // Set the image target of this sibling 69 void setTargetImage(const gl::Context *context, egl::Image *imageTarget); 70 71 // Orphan all EGL image sources and targets 72 angle::Result orphanImages(const gl::Context *context, 73 RefCountObjectReleaser<Image> *outReleaseImage); 74 75 void notifySiblings(angle::SubjectMessage message); 76 77 private: 78 friend class Image; 79 80 // Called from Image only to add a new source image 81 void addImageSource(egl::Image *imageSource); 82 83 // Called from Image only to remove a source image when the Image is being deleted 84 void removeImageSource(egl::Image *imageSource); 85 86 UnorderedSetSiblingSource mSourcesOf; 87 88 BindingPointer<Image> mTargetOf; 89 }; 90 91 // Wrapper for EGLImage sources that are not owned by ANGLE, these often have to do 92 // platform-specific queries for format and size information. 93 class ExternalImageSibling : public ImageSibling 94 { 95 public: 96 ExternalImageSibling(rx::EGLImplFactory *factory, 97 const gl::Context *context, 98 EGLenum target, 99 EGLClientBuffer buffer, 100 const AttributeMap &attribs); 101 ~ExternalImageSibling() override; 102 103 void onDestroy(const egl::Display *display); 104 105 Error initialize(const Display *display, const gl::Context *context); 106 107 gl::Extents getAttachmentSize(const gl::ImageIndex &imageIndex) const override; 108 gl::Format getAttachmentFormat(GLenum binding, const gl::ImageIndex &imageIndex) const override; 109 GLsizei getAttachmentSamples(const gl::ImageIndex &imageIndex) const override; 110 GLuint getLevelCount() const; 111 bool isRenderable(const gl::Context *context, 112 GLenum binding, 113 const gl::ImageIndex &imageIndex) const override; 114 bool isTextureable(const gl::Context *context) const; 115 bool isYUV() const override; 116 bool hasFrontBufferUsage() const override; 117 bool isCubeMap() const; 118 bool hasProtectedContent() const override; 119 120 void onAttach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override; 121 void onDetach(const gl::Context *context, rx::UniqueSerial framebufferSerial) override; 122 GLuint getId() const override; 123 124 gl::InitState initState(GLenum binding, const gl::ImageIndex &imageIndex) const override; 125 void setInitState(GLenum binding, 126 const gl::ImageIndex &imageIndex, 127 gl::InitState initState) override; 128 129 rx::ExternalImageSiblingImpl *getImplementation() const; 130 131 protected: 132 rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override; 133 134 private: 135 // ObserverInterface implementation. 136 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 137 138 std::unique_ptr<rx::ExternalImageSiblingImpl> mImplementation; 139 angle::ObserverBinding mImplObserverBinding; 140 }; 141 142 struct ImageState : private angle::NonCopyable 143 { 144 ImageState(ImageID id, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); 145 ~ImageState(); 146 147 ImageID id; 148 149 EGLLabelKHR label; 150 EGLenum target; 151 gl::ImageIndex imageIndex; 152 ImageSibling *source; 153 154 gl::Format format; 155 bool yuv; 156 bool cubeMap; 157 gl::Extents size; 158 size_t samples; 159 GLuint levelCount; 160 EGLenum colorspace; 161 bool hasProtectedContent; 162 163 mutable angle::SimpleMutex targetsLock; 164 165 static constexpr size_t kTargetsSetSize = 2; 166 angle::FlatUnorderedSet<ImageSibling *, kTargetsSetSize> targets; 167 }; 168 169 class Image final : public ThreadSafeRefCountObject, public LabeledObject 170 { 171 public: 172 Image(rx::EGLImplFactory *factory, 173 ImageID id, 174 const gl::Context *context, 175 EGLenum target, 176 ImageSibling *buffer, 177 const AttributeMap &attribs); 178 179 void onDestroy(const Display *display) override; 180 ~Image() override; 181 id()182 ImageID id() const { return mState.id; } 183 184 void setLabel(EGLLabelKHR label) override; 185 EGLLabelKHR getLabel() const override; 186 187 const gl::Format &getFormat() const; 188 bool isRenderable(const gl::Context *context) const; 189 bool isTexturable(const gl::Context *context) const; 190 bool isYUV() const; 191 bool isExternalImageWithoutIndividualSync() const; 192 bool hasFrontBufferUsage() const; 193 // Returns true only if the eglImage contains a complete cubemap 194 bool isCubeMap() const; 195 size_t getWidth() const; 196 size_t getHeight() const; 197 const gl::Extents &getExtents() const; 198 bool isLayered() const; 199 size_t getSamples() const; 200 GLuint getLevelCount() const; 201 bool hasProtectedContent() const; 202 bool isFixedRatedCompression(const gl::Context *context) const; getColorspaceAttribute()203 EGLenum getColorspaceAttribute() const { return mState.colorspace; } 204 205 Error initialize(const Display *display, const gl::Context *context); 206 207 rx::ImageImpl *getImplementation() const; 208 209 bool orphaned() const; 210 gl::InitState sourceInitState() const; 211 void setInitState(gl::InitState initState); 212 213 Error exportVkImage(void *vkImage, void *vkImageCreateInfo); 214 getContextMutex()215 ContextMutex *getContextMutex() const { return mContextMutex; } 216 getSourceImageIndex()217 const gl::ImageIndex &getSourceImageIndex() const { return mState.imageIndex; } 218 219 private: 220 friend class ImageSibling; 221 222 // Called from ImageSibling only notify the image that a new target sibling exists for state 223 // tracking. 224 void addTargetSibling(ImageSibling *sibling); 225 226 // Called from ImageSibling only to notify the image that a sibling (source or target) has 227 // been respecified and state tracking should be updated. 228 angle::Result orphanSibling(const gl::Context *context, ImageSibling *sibling); 229 230 void notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message); 231 232 ImageState mState; 233 rx::ImageImpl *mImplementation; 234 bool mOrphanedAndNeedsInit; 235 bool mIsTexturable = false; 236 bool mIsRenderable = false; 237 238 ContextMutex *mContextMutex; // Reference counted 239 }; 240 } // namespace egl 241 242 #endif // LIBANGLE_IMAGE_H_ 243