1cb93a386Sopenharmony_ci//
2cb93a386Sopenharmony_ci// Copyright 2014 The ANGLE Project Authors. All rights reserved.
3cb93a386Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
4cb93a386Sopenharmony_ci// found in the LICENSE file.
5cb93a386Sopenharmony_ci//
6cb93a386Sopenharmony_ci
7cb93a386Sopenharmony_ci// FramebufferAttachment.h: Defines the wrapper class gl::FramebufferAttachment, as well as the
8cb93a386Sopenharmony_ci// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#ifndef LIBANGLE_FRAMEBUFFERATTACHMENT_H_
11cb93a386Sopenharmony_ci#define LIBANGLE_FRAMEBUFFERATTACHMENT_H_
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ci#include "angle_gl.h"
14cb93a386Sopenharmony_ci#include "common/angleutils.h"
15cb93a386Sopenharmony_ci#include "libANGLE/Error.h"
16cb93a386Sopenharmony_ci#include "libANGLE/ImageIndex.h"
17cb93a386Sopenharmony_ci#include "libANGLE/Observer.h"
18cb93a386Sopenharmony_ci#include "libANGLE/angletypes.h"
19cb93a386Sopenharmony_ci#include "libANGLE/formatutils.h"
20cb93a386Sopenharmony_ci#include "libANGLE/renderer/FramebufferAttachmentObjectImpl.h"
21cb93a386Sopenharmony_ci
22cb93a386Sopenharmony_cinamespace egl
23cb93a386Sopenharmony_ci{
24cb93a386Sopenharmony_ciclass Surface;
25cb93a386Sopenharmony_ci}
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cinamespace rx
28cb93a386Sopenharmony_ci{
29cb93a386Sopenharmony_ci// An implementation-specific object associated with an attachment.
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ciclass FramebufferAttachmentRenderTarget : angle::NonCopyable
32cb93a386Sopenharmony_ci{
33cb93a386Sopenharmony_ci  public:
34cb93a386Sopenharmony_ci    FramebufferAttachmentRenderTarget() {}
35cb93a386Sopenharmony_ci    virtual ~FramebufferAttachmentRenderTarget() {}
36cb93a386Sopenharmony_ci};
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ciclass FramebufferAttachmentObjectImpl;
39cb93a386Sopenharmony_ci}  // namespace rx
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_cinamespace gl
42cb93a386Sopenharmony_ci{
43cb93a386Sopenharmony_ciclass FramebufferAttachmentObject;
44cb93a386Sopenharmony_ciclass Renderbuffer;
45cb93a386Sopenharmony_ciclass Texture;
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ci// FramebufferAttachment implements a GL framebuffer attachment.
48cb93a386Sopenharmony_ci// Attachments are "light" containers, which store pointers to ref-counted GL objects.
49cb93a386Sopenharmony_ci// We support GL texture (2D/3D/Cube/2D array) and renderbuffer object attachments.
50cb93a386Sopenharmony_ci// Note: Our old naming scheme used the term "Renderbuffer" for both GL renderbuffers and for
51cb93a386Sopenharmony_ci// framebuffer attachments, which confused their usage.
52cb93a386Sopenharmony_ci
53cb93a386Sopenharmony_ciclass FramebufferAttachment final
54cb93a386Sopenharmony_ci{
55cb93a386Sopenharmony_ci  public:
56cb93a386Sopenharmony_ci    FramebufferAttachment();
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ci    FramebufferAttachment(const Context *context,
59cb93a386Sopenharmony_ci                          GLenum type,
60cb93a386Sopenharmony_ci                          GLenum binding,
61cb93a386Sopenharmony_ci                          const ImageIndex &textureIndex,
62cb93a386Sopenharmony_ci                          FramebufferAttachmentObject *resource,
63cb93a386Sopenharmony_ci                          rx::Serial framebufferSerial);
64cb93a386Sopenharmony_ci
65cb93a386Sopenharmony_ci    FramebufferAttachment(FramebufferAttachment &&other);
66cb93a386Sopenharmony_ci    FramebufferAttachment &operator=(FramebufferAttachment &&other);
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ci    ~FramebufferAttachment();
69cb93a386Sopenharmony_ci
70cb93a386Sopenharmony_ci    void detach(const Context *context, rx::Serial framebufferSerial);
71cb93a386Sopenharmony_ci    void attach(const Context *context,
72cb93a386Sopenharmony_ci                GLenum type,
73cb93a386Sopenharmony_ci                GLenum binding,
74cb93a386Sopenharmony_ci                const ImageIndex &textureIndex,
75cb93a386Sopenharmony_ci                FramebufferAttachmentObject *resource,
76cb93a386Sopenharmony_ci                GLsizei numViews,
77cb93a386Sopenharmony_ci                GLuint baseViewIndex,
78cb93a386Sopenharmony_ci                bool isMultiview,
79cb93a386Sopenharmony_ci                GLsizei samples,
80cb93a386Sopenharmony_ci                rx::Serial framebufferSerial);
81cb93a386Sopenharmony_ci
82cb93a386Sopenharmony_ci    // Helper methods
83cb93a386Sopenharmony_ci    GLuint getRedSize() const;
84cb93a386Sopenharmony_ci    GLuint getGreenSize() const;
85cb93a386Sopenharmony_ci    GLuint getBlueSize() const;
86cb93a386Sopenharmony_ci    GLuint getAlphaSize() const;
87cb93a386Sopenharmony_ci    GLuint getDepthSize() const;
88cb93a386Sopenharmony_ci    GLuint getStencilSize() const;
89cb93a386Sopenharmony_ci    GLenum getComponentType() const;
90cb93a386Sopenharmony_ci    GLenum getColorEncoding() const;
91cb93a386Sopenharmony_ci
92cb93a386Sopenharmony_ci    bool isTextureWithId(TextureID textureId) const
93cb93a386Sopenharmony_ci    {
94cb93a386Sopenharmony_ci        return mType == GL_TEXTURE && id() == textureId.value;
95cb93a386Sopenharmony_ci    }
96cb93a386Sopenharmony_ci    bool isExternalTexture() const
97cb93a386Sopenharmony_ci    {
98cb93a386Sopenharmony_ci        return mType == GL_TEXTURE && getTextureImageIndex().getType() == gl::TextureType::External;
99cb93a386Sopenharmony_ci    }
100cb93a386Sopenharmony_ci    bool isRenderbufferWithId(GLuint renderbufferId) const
101cb93a386Sopenharmony_ci    {
102cb93a386Sopenharmony_ci        return mType == GL_RENDERBUFFER && id() == renderbufferId;
103cb93a386Sopenharmony_ci    }
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_ci    GLenum getBinding() const { return mTarget.binding(); }
106cb93a386Sopenharmony_ci    GLuint id() const;
107cb93a386Sopenharmony_ci
108cb93a386Sopenharmony_ci    // These methods are only legal to call on Texture attachments
109cb93a386Sopenharmony_ci    const ImageIndex &getTextureImageIndex() const;
110cb93a386Sopenharmony_ci    TextureTarget cubeMapFace() const;
111cb93a386Sopenharmony_ci    GLint mipLevel() const;
112cb93a386Sopenharmony_ci    GLint layer() const;
113cb93a386Sopenharmony_ci    bool isLayered() const;
114cb93a386Sopenharmony_ci
115cb93a386Sopenharmony_ci    GLsizei getNumViews() const { return mNumViews; }
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ci    bool isMultiview() const;
118cb93a386Sopenharmony_ci    GLint getBaseViewIndex() const;
119cb93a386Sopenharmony_ci
120cb93a386Sopenharmony_ci    bool isRenderToTexture() const;
121cb93a386Sopenharmony_ci    GLsizei getRenderToTextureSamples() const;
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ci    // The size of the underlying resource the attachment points to. The 'depth' value will
124cb93a386Sopenharmony_ci    // correspond to a 3D texture depth or the layer count of a 2D array texture. For Surfaces and
125cb93a386Sopenharmony_ci    // Renderbuffers, it will always be 1.
126cb93a386Sopenharmony_ci    Extents getSize() const;
127cb93a386Sopenharmony_ci    Format getFormat() const;
128cb93a386Sopenharmony_ci    GLsizei getSamples() const;
129cb93a386Sopenharmony_ci    // This will always return the actual sample count of the attachment even if
130cb93a386Sopenharmony_ci    // render_to_texture extension is active on this FBattachment object.
131cb93a386Sopenharmony_ci    GLsizei getResourceSamples() const;
132cb93a386Sopenharmony_ci    GLenum type() const { return mType; }
133cb93a386Sopenharmony_ci    bool isAttached() const { return mType != GL_NONE; }
134cb93a386Sopenharmony_ci    bool isRenderable(const Context *context) const;
135cb93a386Sopenharmony_ci    bool isYUV() const;
136cb93a386Sopenharmony_ci
137cb93a386Sopenharmony_ci    Renderbuffer *getRenderbuffer() const;
138cb93a386Sopenharmony_ci    Texture *getTexture() const;
139cb93a386Sopenharmony_ci    const egl::Surface *getSurface() const;
140cb93a386Sopenharmony_ci    FramebufferAttachmentObject *getResource() const;
141cb93a386Sopenharmony_ci    InitState initState() const;
142cb93a386Sopenharmony_ci    angle::Result initializeContents(const Context *context);
143cb93a386Sopenharmony_ci    void setInitState(InitState initState) const;
144cb93a386Sopenharmony_ci
145cb93a386Sopenharmony_ci    // "T" must be static_castable from FramebufferAttachmentRenderTarget
146cb93a386Sopenharmony_ci    template <typename T>
147cb93a386Sopenharmony_ci    angle::Result getRenderTarget(const Context *context, GLsizei samples, T **rtOut) const
148cb93a386Sopenharmony_ci    {
149cb93a386Sopenharmony_ci        static_assert(std::is_base_of<rx::FramebufferAttachmentRenderTarget, T>(),
150cb93a386Sopenharmony_ci                      "Invalid RenderTarget class.");
151cb93a386Sopenharmony_ci        return getRenderTargetImpl(
152cb93a386Sopenharmony_ci            context, samples, reinterpret_cast<rx::FramebufferAttachmentRenderTarget **>(rtOut));
153cb93a386Sopenharmony_ci    }
154cb93a386Sopenharmony_ci
155cb93a386Sopenharmony_ci    bool operator==(const FramebufferAttachment &other) const;
156cb93a386Sopenharmony_ci    bool operator!=(const FramebufferAttachment &other) const;
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_ci    static const GLsizei kDefaultNumViews;
159cb93a386Sopenharmony_ci    static const GLint kDefaultBaseViewIndex;
160cb93a386Sopenharmony_ci    static const GLint kDefaultRenderToTextureSamples;
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_ci  private:
163cb93a386Sopenharmony_ci    angle::Result getRenderTargetImpl(const Context *context,
164cb93a386Sopenharmony_ci                                      GLsizei samples,
165cb93a386Sopenharmony_ci                                      rx::FramebufferAttachmentRenderTarget **rtOut) const;
166cb93a386Sopenharmony_ci
167cb93a386Sopenharmony_ci    // A framebuffer attachment points to one of three types of resources: Renderbuffers,
168cb93a386Sopenharmony_ci    // Textures and egl::Surface. The "Target" struct indicates which part of the
169cb93a386Sopenharmony_ci    // object an attachment references. For the three types:
170cb93a386Sopenharmony_ci    //   - a Renderbuffer has a unique renderable target, and needs no target index
171cb93a386Sopenharmony_ci    //   - a Texture has targets for every image and uses an ImageIndex
172cb93a386Sopenharmony_ci    //   - a Surface has targets for Color and Depth/Stencil, and uses the attachment binding
173cb93a386Sopenharmony_ci    class Target
174cb93a386Sopenharmony_ci    {
175cb93a386Sopenharmony_ci      public:
176cb93a386Sopenharmony_ci        Target();
177cb93a386Sopenharmony_ci        Target(GLenum binding, const ImageIndex &imageIndex);
178cb93a386Sopenharmony_ci        Target(const Target &other);
179cb93a386Sopenharmony_ci        Target &operator=(const Target &other);
180cb93a386Sopenharmony_ci
181cb93a386Sopenharmony_ci        GLenum binding() const { return mBinding; }
182cb93a386Sopenharmony_ci        const ImageIndex &textureIndex() const { return mTextureIndex; }
183cb93a386Sopenharmony_ci
184cb93a386Sopenharmony_ci      private:
185cb93a386Sopenharmony_ci        GLenum mBinding;
186cb93a386Sopenharmony_ci        ImageIndex mTextureIndex;
187cb93a386Sopenharmony_ci    };
188cb93a386Sopenharmony_ci
189cb93a386Sopenharmony_ci    GLenum mType;
190cb93a386Sopenharmony_ci    Target mTarget;
191cb93a386Sopenharmony_ci    FramebufferAttachmentObject *mResource;
192cb93a386Sopenharmony_ci    GLsizei mNumViews;
193cb93a386Sopenharmony_ci    bool mIsMultiview;
194cb93a386Sopenharmony_ci    GLint mBaseViewIndex;
195cb93a386Sopenharmony_ci    // A single-sampled texture can be attached to a framebuffer either as single-sampled or as
196cb93a386Sopenharmony_ci    // multisampled-render-to-texture.  In the latter case, |mRenderToTextureSamples| will contain
197cb93a386Sopenharmony_ci    // the number of samples.  For renderbuffers, the number of samples is inherited from the
198cb93a386Sopenharmony_ci    // renderbuffer itself.
199cb93a386Sopenharmony_ci    //
200cb93a386Sopenharmony_ci    // Note that textures cannot change storage between single and multisample once attached to a
201cb93a386Sopenharmony_ci    // framebuffer.  Renderbuffers instead can, and caching the number of renderbuffer samples here
202cb93a386Sopenharmony_ci    // can lead to stale data.
203cb93a386Sopenharmony_ci    GLsizei mRenderToTextureSamples;
204cb93a386Sopenharmony_ci};
205cb93a386Sopenharmony_ci
206cb93a386Sopenharmony_ci// A base class for objects that FBO Attachments may point to.
207cb93a386Sopenharmony_ciclass FramebufferAttachmentObject : public angle::Subject, public angle::ObserverInterface
208cb93a386Sopenharmony_ci{
209cb93a386Sopenharmony_ci  public:
210cb93a386Sopenharmony_ci    FramebufferAttachmentObject();
211cb93a386Sopenharmony_ci    ~FramebufferAttachmentObject() override;
212cb93a386Sopenharmony_ci
213cb93a386Sopenharmony_ci    virtual Extents getAttachmentSize(const ImageIndex &imageIndex) const                  = 0;
214cb93a386Sopenharmony_ci    virtual Format getAttachmentFormat(GLenum binding, const ImageIndex &imageIndex) const = 0;
215cb93a386Sopenharmony_ci    virtual GLsizei getAttachmentSamples(const ImageIndex &imageIndex) const               = 0;
216cb93a386Sopenharmony_ci    virtual bool isRenderable(const Context *context,
217cb93a386Sopenharmony_ci                              GLenum binding,
218cb93a386Sopenharmony_ci                              const ImageIndex &imageIndex) const                          = 0;
219cb93a386Sopenharmony_ci    virtual bool isYUV() const                                                             = 0;
220cb93a386Sopenharmony_ci    virtual bool hasProtectedContent() const                                               = 0;
221cb93a386Sopenharmony_ci
222cb93a386Sopenharmony_ci    virtual void onAttach(const Context *context, rx::Serial framebufferSerial) = 0;
223cb93a386Sopenharmony_ci    virtual void onDetach(const Context *context, rx::Serial framebufferSerial) = 0;
224cb93a386Sopenharmony_ci    virtual GLuint getId() const                                                = 0;
225cb93a386Sopenharmony_ci
226cb93a386Sopenharmony_ci    // These are used for robust resource initialization.
227cb93a386Sopenharmony_ci    virtual InitState initState(const ImageIndex &imageIndex) const              = 0;
228cb93a386Sopenharmony_ci    virtual void setInitState(const ImageIndex &imageIndex, InitState initState) = 0;
229cb93a386Sopenharmony_ci
230cb93a386Sopenharmony_ci    angle::Result getAttachmentRenderTarget(const Context *context,
231cb93a386Sopenharmony_ci                                            GLenum binding,
232cb93a386Sopenharmony_ci                                            const ImageIndex &imageIndex,
233cb93a386Sopenharmony_ci                                            GLsizei samples,
234cb93a386Sopenharmony_ci                                            rx::FramebufferAttachmentRenderTarget **rtOut) const;
235cb93a386Sopenharmony_ci
236cb93a386Sopenharmony_ci    angle::Result initializeContents(const Context *context, const ImageIndex &imageIndex);
237cb93a386Sopenharmony_ci
238cb93a386Sopenharmony_ci  protected:
239cb93a386Sopenharmony_ci    virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
240cb93a386Sopenharmony_ci};
241cb93a386Sopenharmony_ci
242cb93a386Sopenharmony_ciinline const ImageIndex &FramebufferAttachment::getTextureImageIndex() const
243cb93a386Sopenharmony_ci{
244cb93a386Sopenharmony_ci    ASSERT(type() == GL_TEXTURE);
245cb93a386Sopenharmony_ci    return mTarget.textureIndex();
246cb93a386Sopenharmony_ci}
247cb93a386Sopenharmony_ci
248cb93a386Sopenharmony_ciinline Extents FramebufferAttachment::getSize() const
249cb93a386Sopenharmony_ci{
250cb93a386Sopenharmony_ci    ASSERT(mResource);
251cb93a386Sopenharmony_ci    return mResource->getAttachmentSize(mTarget.textureIndex());
252cb93a386Sopenharmony_ci}
253cb93a386Sopenharmony_ci
254cb93a386Sopenharmony_ciinline Format FramebufferAttachment::getFormat() const
255cb93a386Sopenharmony_ci{
256cb93a386Sopenharmony_ci    ASSERT(mResource);
257cb93a386Sopenharmony_ci    return mResource->getAttachmentFormat(mTarget.binding(), mTarget.textureIndex());
258cb93a386Sopenharmony_ci}
259cb93a386Sopenharmony_ci
260cb93a386Sopenharmony_ciinline GLsizei FramebufferAttachment::getSamples() const
261cb93a386Sopenharmony_ci{
262cb93a386Sopenharmony_ci    return isRenderToTexture() ? getRenderToTextureSamples() : getResourceSamples();
263cb93a386Sopenharmony_ci}
264cb93a386Sopenharmony_ci
265cb93a386Sopenharmony_ciinline GLsizei FramebufferAttachment::getResourceSamples() const
266cb93a386Sopenharmony_ci{
267cb93a386Sopenharmony_ci    ASSERT(mResource);
268cb93a386Sopenharmony_ci    return mResource->getAttachmentSamples(mTarget.textureIndex());
269cb93a386Sopenharmony_ci}
270cb93a386Sopenharmony_ci
271cb93a386Sopenharmony_ciinline angle::Result FramebufferAttachment::getRenderTargetImpl(
272cb93a386Sopenharmony_ci    const Context *context,
273cb93a386Sopenharmony_ci    GLsizei samples,
274cb93a386Sopenharmony_ci    rx::FramebufferAttachmentRenderTarget **rtOut) const
275cb93a386Sopenharmony_ci{
276cb93a386Sopenharmony_ci    ASSERT(mResource);
277cb93a386Sopenharmony_ci    return mResource->getAttachmentRenderTarget(context, mTarget.binding(), mTarget.textureIndex(),
278cb93a386Sopenharmony_ci                                                samples, rtOut);
279cb93a386Sopenharmony_ci}
280cb93a386Sopenharmony_ci
281cb93a386Sopenharmony_ciinline bool FramebufferAttachment::isRenderable(const Context *context) const
282cb93a386Sopenharmony_ci{
283cb93a386Sopenharmony_ci    ASSERT(mResource);
284cb93a386Sopenharmony_ci    return mResource->isRenderable(context, mTarget.binding(), mTarget.textureIndex());
285cb93a386Sopenharmony_ci}
286cb93a386Sopenharmony_ci
287cb93a386Sopenharmony_ciinline bool FramebufferAttachment::isYUV() const
288cb93a386Sopenharmony_ci{
289cb93a386Sopenharmony_ci    ASSERT(mResource);
290cb93a386Sopenharmony_ci    return mResource->isYUV();
291cb93a386Sopenharmony_ci}
292cb93a386Sopenharmony_ci
293cb93a386Sopenharmony_ci}  // namespace gl
294cb93a386Sopenharmony_ci
295cb93a386Sopenharmony_ci#endif  // LIBANGLE_FRAMEBUFFERATTACHMENT_H_
296