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