• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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