• 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/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