• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2018 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 // ImageEGL.cpp: Implements the rx::ImageEGL class.
8 
9 #include "libANGLE/renderer/gl/egl/ImageEGL.h"
10 
11 #include "common/utilities.h"
12 #include "libANGLE/Context.h"
13 #include "libANGLE/renderer/gl/FunctionsGL.h"
14 #include "libANGLE/renderer/gl/RenderbufferGL.h"
15 #include "libANGLE/renderer/gl/StateManagerGL.h"
16 #include "libANGLE/renderer/gl/TextureGL.h"
17 #include "libANGLE/renderer/gl/egl/ContextEGL.h"
18 #include "libANGLE/renderer/gl/egl/ExternalImageSiblingEGL.h"
19 #include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
20 
21 namespace rx
22 {
23 
ImageEGL(const egl::ImageState & state,const gl::Context * context,EGLenum target,const egl::AttributeMap & attribs,const FunctionsEGL * egl)24 ImageEGL::ImageEGL(const egl::ImageState &state,
25                    const gl::Context *context,
26                    EGLenum target,
27                    const egl::AttributeMap &attribs,
28                    const FunctionsEGL *egl)
29     : ImageGL(state),
30       mEGL(egl),
31       mContext(EGL_NO_CONTEXT),
32       mTarget(target),
33       mPreserveImage(false),
34       mImage(EGL_NO_IMAGE)
35 {
36     if (context)
37     {
38         mContext = GetImplAs<ContextEGL>(context)->getContext();
39     }
40     mPreserveImage = attribs.get(EGL_IMAGE_PRESERVED, EGL_FALSE) == EGL_TRUE;
41 }
42 
~ImageEGL()43 ImageEGL::~ImageEGL()
44 {
45     mEGL->destroyImageKHR(mImage);
46 }
47 
initialize(const egl::Display * display)48 egl::Error ImageEGL::initialize(const egl::Display *display)
49 {
50     EGLClientBuffer buffer = nullptr;
51     angle::FastVector<EGLint, 8> attributes;
52 
53     if (egl::IsTextureTarget(mTarget))
54     {
55         attributes.push_back(EGL_GL_TEXTURE_LEVEL);
56         attributes.push_back(mState.imageIndex.getLevelIndex());
57 
58         if (mState.imageIndex.has3DLayer())
59         {
60             attributes.push_back(EGL_GL_TEXTURE_ZOFFSET);
61             attributes.push_back(mState.imageIndex.getLayerIndex());
62         }
63 
64         const TextureGL *textureGL = GetImplAs<TextureGL>(GetAs<gl::Texture>(mState.source));
65         buffer                = gl_egl::GLObjectHandleToEGLClientBuffer(textureGL->getTextureID());
66         mNativeInternalFormat = textureGL->getNativeInternalFormat(mState.imageIndex);
67     }
68     else if (egl::IsRenderbufferTarget(mTarget))
69     {
70         const RenderbufferGL *renderbufferGL =
71             GetImplAs<RenderbufferGL>(GetAs<gl::Renderbuffer>(mState.source));
72         buffer = gl_egl::GLObjectHandleToEGLClientBuffer(renderbufferGL->getRenderbufferID());
73         mNativeInternalFormat = renderbufferGL->getNativeInternalFormat();
74     }
75     else if (egl::IsExternalImageTarget(mTarget))
76     {
77         const ExternalImageSiblingEGL *externalImageSibling =
78             GetImplAs<ExternalImageSiblingEGL>(GetAs<egl::ExternalImageSibling>(mState.source));
79         buffer                = externalImageSibling->getBuffer();
80         mNativeInternalFormat = externalImageSibling->getFormat().info->sizedInternalFormat;
81 
82         // Add any additional attributes this type of image sibline requires
83         std::vector<EGLint> tmp_attributes;
84         externalImageSibling->getImageCreationAttributes(&tmp_attributes);
85 
86         attributes.reserve(attributes.size() + tmp_attributes.size());
87         for (EGLint attribute : tmp_attributes)
88         {
89             attributes.push_back(attribute);
90         }
91     }
92     else
93     {
94         UNREACHABLE();
95     }
96 
97     attributes.push_back(EGL_IMAGE_PRESERVED);
98     attributes.push_back(mPreserveImage ? EGL_TRUE : EGL_FALSE);
99 
100     attributes.push_back(EGL_NONE);
101 
102     mImage = mEGL->createImageKHR(mContext, mTarget, buffer, attributes.data());
103     if (mImage == EGL_NO_IMAGE)
104     {
105         return egl::EglBadAlloc() << "eglCreateImage failed with " << egl::Error(mEGL->getError());
106     }
107 
108     return egl::NoError();
109 }
110 
orphan(const gl::Context * context,egl::ImageSibling * sibling)111 angle::Result ImageEGL::orphan(const gl::Context *context, egl::ImageSibling *sibling)
112 {
113     // Nothing to do, the native EGLImage will orphan automatically.
114     return angle::Result::Continue;
115 }
116 
setTexture2D(const gl::Context * context,gl::TextureType type,TextureGL * texture,GLenum * outInternalFormat)117 angle::Result ImageEGL::setTexture2D(const gl::Context *context,
118                                      gl::TextureType type,
119                                      TextureGL *texture,
120                                      GLenum *outInternalFormat)
121 {
122     const FunctionsGL *functionsGL = GetFunctionsGL(context);
123     StateManagerGL *stateManager   = GetStateManagerGL(context);
124 
125     // Make sure this texture is bound
126     stateManager->bindTexture(type, texture->getTextureID());
127 
128     // Bind the image to the texture
129     functionsGL->eGLImageTargetTexture2DOES(ToGLenum(type), mImage);
130     *outInternalFormat = mNativeInternalFormat;
131 
132     return angle::Result::Continue;
133 }
134 
setRenderbufferStorage(const gl::Context * context,RenderbufferGL * renderbuffer,GLenum * outInternalFormat)135 angle::Result ImageEGL::setRenderbufferStorage(const gl::Context *context,
136                                                RenderbufferGL *renderbuffer,
137                                                GLenum *outInternalFormat)
138 {
139     const FunctionsGL *functionsGL = GetFunctionsGL(context);
140     StateManagerGL *stateManager   = GetStateManagerGL(context);
141 
142     // Make sure this renderbuffer is bound
143     stateManager->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer->getRenderbufferID());
144 
145     // Bind the image to the renderbuffer
146     functionsGL->eGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);
147     *outInternalFormat = mNativeInternalFormat;
148 
149     return angle::Result::Continue;
150 }
151 
152 }  // namespace rx
153