• 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, public angle::ObserverInterface
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 
55     // ObserverInterface implementation
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)56     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override
57     {
58         // default to no-op.
59     }
60 
61   protected:
62     // Set the image target of this sibling
63     void setTargetImage(const gl::Context *context, egl::Image *imageTarget);
64 
65     // Orphan all EGL image sources and targets
66     angle::Result orphanImages(const gl::Context *context);
67 
68     void notifySiblings(angle::SubjectMessage message);
69 
70   private:
71     friend class Image;
72 
73     // Called from Image only to add a new source image
74     void addImageSource(egl::Image *imageSource);
75 
76     // Called from Image only to remove a source image when the Image is being deleted
77     void removeImageSource(egl::Image *imageSource);
78 
79     std::set<Image *> 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);
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     bool isRenderable(const gl::Context *context,
103                       GLenum binding,
104                       const gl::ImageIndex &imageIndex) const override;
105     bool isTextureable(const gl::Context *context) const;
106 
107     void onAttach(const gl::Context *context) override;
108     void onDetach(const gl::Context *context) override;
109     GLuint getId() const override;
110 
111     gl::InitState initState(const gl::ImageIndex &imageIndex) const override;
112     void setInitState(const gl::ImageIndex &imageIndex, gl::InitState initState) override;
113 
114     rx::ExternalImageSiblingImpl *getImplementation() const;
115 
116   protected:
117     rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const override;
118 
119   private:
120     std::unique_ptr<rx::ExternalImageSiblingImpl> mImplementation;
121 };
122 
123 struct ImageState : private angle::NonCopyable
124 {
125     ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs);
126     ~ImageState();
127 
128     EGLLabelKHR label;
129     EGLenum target;
130     gl::ImageIndex imageIndex;
131     ImageSibling *source;
132     std::set<ImageSibling *> targets;
133 
134     gl::Format format;
135     gl::Extents size;
136     size_t samples;
137     EGLenum sourceType;
138     EGLenum colorspace;
139 };
140 
141 class Image final : public RefCountObject, public LabeledObject
142 {
143   public:
144     Image(rx::EGLImplFactory *factory,
145           const gl::Context *context,
146           EGLenum target,
147           ImageSibling *buffer,
148           const AttributeMap &attribs);
149 
150     void onDestroy(const Display *display) override;
151     ~Image() override;
152 
153     void setLabel(EGLLabelKHR label) override;
154     EGLLabelKHR getLabel() const override;
155 
156     const gl::Format &getFormat() const;
157     bool isRenderable(const gl::Context *context) const;
158     bool isTexturable(const gl::Context *context) const;
159     size_t getWidth() const;
160     size_t getHeight() const;
161     size_t getSamples() const;
162 
163     Error initialize(const Display *display);
164 
165     rx::ImageImpl *getImplementation() const;
166 
167     bool orphaned() const;
168     gl::InitState sourceInitState() const;
169     void setInitState(gl::InitState initState);
170 
171   private:
172     friend class ImageSibling;
173 
174     // Called from ImageSibling only notify the image that a new target sibling exists for state
175     // tracking.
176     void addTargetSibling(ImageSibling *sibling);
177 
178     // Called from ImageSibling only to notify the image that a sibling (source or target) has
179     // been respecified and state tracking should be updated.
180     angle::Result orphanSibling(const gl::Context *context, ImageSibling *sibling);
181 
182     void notifySiblings(const ImageSibling *notifier, angle::SubjectMessage message);
183 
184     ImageState mState;
185     rx::ImageImpl *mImplementation;
186     bool mOrphanedAndNeedsInit;
187 };
188 }  // namespace egl
189 
190 #endif  // LIBANGLE_IMAGE_H_
191