1 //
2 // Copyright (c) 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/Error.h"
15 #include "libANGLE/FramebufferAttachment.h"
16 #include "libANGLE/RefCountObject.h"
17 #include "libANGLE/formatutils.h"
18 
19 #include <set>
20 
21 namespace rx
22 {
23 class EGLImplFactory;
24 class ImageImpl;
25 }
26 
27 namespace egl
28 {
29 class Image;
30 
31 // Only currently Renderbuffers and Textures can be bound with images. This makes the relationship
32 // explicit, and also ensures that an image sibling can determine if it's been initialized or not,
33 // which is important for the robust resource init extension with Textures and EGLImages.
34 class ImageSibling : public gl::RefCountObject, public gl::FramebufferAttachmentObject
35 {
36   public:
37     ImageSibling(GLuint id);
38     ~ImageSibling() override;
39 
40     bool isEGLImageTarget() const;
41     gl::InitState sourceEGLImageInitState() const;
42     void setSourceEGLImageInitState(gl::InitState initState) const;
43 
44   protected:
45     // Set the image target of this sibling
46     void setTargetImage(const gl::Context *context, egl::Image *imageTarget);
47 
48     // Orphan all EGL image sources and targets
49     gl::Error orphanImages(const gl::Context *context);
50 
51   private:
52     friend class Image;
53 
54     // Called from Image only to add a new source image
55     void addImageSource(egl::Image *imageSource);
56 
57     // Called from Image only to remove a source image when the Image is being deleted
58     void removeImageSource(egl::Image *imageSource);
59 
60     std::set<Image *> mSourcesOf;
61     gl::BindingPointer<Image> mTargetOf;
62 };
63 
64 struct ImageState : private angle::NonCopyable
65 {
66     ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs);
67     ~ImageState();
68 
69     gl::ImageIndex imageIndex;
70     gl::BindingPointer<ImageSibling> source;
71     std::set<ImageSibling *> targets;
72 };
73 
74 class Image final : public gl::RefCountObject
75 {
76   public:
77     Image(rx::EGLImplFactory *factory,
78           EGLenum target,
79           ImageSibling *buffer,
80           const AttributeMap &attribs);
81 
82     gl::Error onDestroy(const gl::Context *context) override;
83     ~Image() override;
84 
85     const gl::Format &getFormat() const;
86     size_t getWidth() const;
87     size_t getHeight() const;
88     size_t getSamples() const;
89 
90     Error initialize();
91 
92     rx::ImageImpl *getImplementation() const;
93 
94     bool orphaned() const;
95     gl::InitState sourceInitState() const;
96     void setInitState(gl::InitState initState);
97 
98   private:
99     friend class ImageSibling;
100 
101     // Called from ImageSibling only notify the image that a new target sibling exists for state
102     // tracking.
103     void addTargetSibling(ImageSibling *sibling);
104 
105     // Called from ImageSibling only to notify the image that a sibling (source or target) has
106     // been respecified and state tracking should be updated.
107     gl::Error orphanSibling(const gl::Context *context, ImageSibling *sibling);
108 
109     ImageState mState;
110     rx::ImageImpl *mImplementation;
111     bool mOrphanedAndNeedsInit;
112 };
113 }  // namespace egl
114 
115 #endif  // LIBANGLE_IMAGE_H_
116