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