• 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     std::vector<EGLint> 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         externalImageSibling->getImageCreationAttributes(&attributes);
84     }
85     else
86     {
87         UNREACHABLE();
88     }
89 
90     attributes.push_back(EGL_IMAGE_PRESERVED);
91     attributes.push_back(mPreserveImage ? EGL_TRUE : EGL_FALSE);
92 
93     attributes.push_back(EGL_NONE);
94 
95     mImage = mEGL->createImageKHR(mContext, mTarget, buffer, attributes.data());
96     if (mImage == EGL_NO_IMAGE)
97     {
98         return egl::EglBadAlloc() << "eglCreateImage failed with " << egl::Error(mEGL->getError());
99     }
100 
101     return egl::NoError();
102 }
103 
orphan(const gl::Context * context,egl::ImageSibling * sibling)104 angle::Result ImageEGL::orphan(const gl::Context *context, egl::ImageSibling *sibling)
105 {
106     // Nothing to do, the native EGLImage will orphan automatically.
107     return angle::Result::Continue;
108 }
109 
setTexture2D(const gl::Context * context,gl::TextureType type,TextureGL * texture,GLenum * outInternalFormat)110 angle::Result ImageEGL::setTexture2D(const gl::Context *context,
111                                      gl::TextureType type,
112                                      TextureGL *texture,
113                                      GLenum *outInternalFormat)
114 {
115     const FunctionsGL *functionsGL = GetFunctionsGL(context);
116     StateManagerGL *stateManager   = GetStateManagerGL(context);
117 
118     // Make sure this texture is bound
119     stateManager->bindTexture(type, texture->getTextureID());
120 
121     // Bind the image to the texture
122     functionsGL->eGLImageTargetTexture2DOES(ToGLenum(type), mImage);
123     *outInternalFormat = mNativeInternalFormat;
124 
125     return angle::Result::Continue;
126 }
127 
setRenderbufferStorage(const gl::Context * context,RenderbufferGL * renderbuffer,GLenum * outInternalFormat)128 angle::Result ImageEGL::setRenderbufferStorage(const gl::Context *context,
129                                                RenderbufferGL *renderbuffer,
130                                                GLenum *outInternalFormat)
131 {
132     const FunctionsGL *functionsGL = GetFunctionsGL(context);
133     StateManagerGL *stateManager   = GetStateManagerGL(context);
134 
135     // Make sure this renderbuffer is bound
136     stateManager->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer->getRenderbufferID());
137 
138     // Bind the image to the renderbuffer
139     functionsGL->eGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);
140     *outInternalFormat = mNativeInternalFormat;
141 
142     return angle::Result::Continue;
143 }
144 
145 }  // namespace rx
146