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