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