• 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     bool isRenderable(const gl::Context *context,
100                       GLenum binding,
101                       const gl::ImageIndex &imageIndex) const override;
102     bool isTextureable(const gl::Context *context) const;
103     bool isYUV() const override;
104     bool hasProtectedContent() const override;
105 
106     void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override;
107     void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override;
108     GLuint getId() const override;
109 
110     gl::InitState initState(const gl::ImageIndex &imageIndex) const override;
111     void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override;
112 
113     rx::ExternalImageSiblingImpl *getImplementation() const;
114 
115   protected:
116     rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
117 
118   private:
119     // ObserverInterface implementation.
120     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
121 
122     std::unique_ptr<rx::ExternalImageSiblingImpl> mImplementation;
123     angle::ObserverBinding mImplObserverBinding;
124 };
125 
126 struct ImageState : private angle::NonCopyable
127 {
128     ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs);
129     ~ImageState();
130 
131     EGLLabelKHR label;
132     EGLenum target;
133     gl::ImageIndex imageIndex;
134     ImageSibling *source;
135     std::set<ImageSibling *> targets;
136 
137     gl::Format format;
138     bool yuv;
139     gl::Extents size;
140     size_t samples;
141     EGLenum sourceType;
142     EGLenum colorspace;
143     bool hasProtectedContent;
144 };
145 
146 class Image final : public RefCountObject, public LabeledObject
147 {
148   public:
149     Image(rx::EGLImplFactory *factory,
150           const gl::Context *context,
151           EGLenum target,
152           ImageSibling *buffer,
153           const AttributeMap &attribs);
154 
155     void onDestroy(const Display *display) override;
156     ~Image() override;
157 
158     void setLabel(EGLLabelKHR label) override;
159     EGLLabelKHR getLabel() const override;
160 
161     const gl::Format &getFormat() const;
162     bool isRenderable(const gl::Context *context) const;
163     bool isTexturable(const gl::Context *context) const;
164     bool isYUV() const;
165     size_t getWidth() const;
166     size_t getHeight() const;
167     bool isLayered() const;
168     size_t getSamples() const;
169     bool hasProtectedContent() const;
170 
171     Error initialize(const Display *display);
172 
173     rx::ImageImpl *getImplementation() const;
174 
175     bool orphaned() const;
176     gl::InitState sourceInitState() const;
177     void setInitState(gl::InitState initState);
178 
179     Error exportVkImage(void *vkImage, void *vkImageCreateInfo);
180 
181   private:
182     friend class ImageSibling;
183 
184     // Called from ImageSibling only notify the image that a new target sibling exists for state
185     // tracking.
186     void addTargetSibling(ImageSibling *sibling);
187 
188     // Called from ImageSibling only to notify the image that a sibling (source or target) has
189     // been respecified and state tracking should be updated.
190     angle::Result orphanSibling(const gl::Context *context, ImageSibling *sibling);
191 
192     void notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message);
193 
194     ImageState mState;
195     rx::ImageImpl *mImplementation;
196     bool mOrphanedAndNeedsInit;
197 };
198 }  // namespace egl
199 
200 #endif  // LIBANGLE_IMAGE_H_
201