blob: 24866b971882773143fb4739070eadcae3c2b9d1 [file] [log] [blame]
Geoff Langa8406172015-07-21 16:53:39 -04001//
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.cpp: Implements the egl::Image class representing the EGLimage object.
8
9#include "libANGLE/Image.h"
10
11#include "common/debug.h"
12#include "common/utilities.h"
Geoff Lange1a057e2018-06-07 15:09:00 -040013#include "libANGLE/Renderbuffer.h"
14#include "libANGLE/Texture.h"
Geoff Langa8406172015-07-21 16:53:39 -040015#include "libANGLE/angletypes.h"
Jamie Madilla3944d42016-07-22 22:13:26 -040016#include "libANGLE/formatutils.h"
Jamie Madill76b8f462017-04-21 12:23:40 -040017#include "libANGLE/renderer/EGLImplFactory.h"
Geoff Langa8406172015-07-21 16:53:39 -040018#include "libANGLE/renderer/ImageImpl.h"
19
20namespace egl
21{
Jamie Madill76b8f462017-04-21 12:23:40 -040022
23namespace
24{
25gl::ImageIndex GetImageIndex(EGLenum eglTarget, const egl::AttributeMap &attribs)
26{
27 if (eglTarget == EGL_GL_RENDERBUFFER)
28 {
Jamie Madillcc129372018-04-12 09:13:18 -040029 return gl::ImageIndex();
Jamie Madill76b8f462017-04-21 12:23:40 -040030 }
31
Corentin Wallezf0e89be2017-11-08 14:00:32 -080032 gl::TextureTarget target = egl_gl::EGLImageTargetToTextureTarget(eglTarget);
Geoff Lange1a057e2018-06-07 15:09:00 -040033 GLint mip = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0));
34 GLint layer = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0));
Jamie Madill76b8f462017-04-21 12:23:40 -040035
Corentin Wallezf0e89be2017-11-08 14:00:32 -080036 if (target == gl::TextureTarget::_3D)
Jamie Madill76b8f462017-04-21 12:23:40 -040037 {
38 return gl::ImageIndex::Make3D(mip, layer);
39 }
40 else
41 {
42 ASSERT(layer == 0);
Jamie Madillcc129372018-04-12 09:13:18 -040043 return gl::ImageIndex::MakeFromTarget(target, mip);
Jamie Madill76b8f462017-04-21 12:23:40 -040044 }
45}
46} // anonymous namespace
47
Jamie Madill05b35b22017-10-03 09:01:44 -040048ImageSibling::ImageSibling(GLuint id)
49 : RefCountObject(id), FramebufferAttachmentObject(), mSourcesOf(), mTargetOf()
Geoff Langa8406172015-07-21 16:53:39 -040050{
51}
52
53ImageSibling::~ImageSibling()
54{
55 // EGL images should hold a ref to their targets and siblings, a Texture should not be deletable
56 // while it is attached to an EGL image.
Jamie Madill4928b7c2017-06-20 12:57:39 -040057 // Child class should orphan images before destruction.
Geoff Langa8406172015-07-21 16:53:39 -040058 ASSERT(mSourcesOf.empty());
Jamie Madill4928b7c2017-06-20 12:57:39 -040059 ASSERT(mTargetOf.get() == nullptr);
Geoff Langa8406172015-07-21 16:53:39 -040060}
61
Jamie Madill4928b7c2017-06-20 12:57:39 -040062void ImageSibling::setTargetImage(const gl::Context *context, egl::Image *imageTarget)
Geoff Langa8406172015-07-21 16:53:39 -040063{
64 ASSERT(imageTarget != nullptr);
Jamie Madill4928b7c2017-06-20 12:57:39 -040065 mTargetOf.set(context, imageTarget);
Geoff Langa8406172015-07-21 16:53:39 -040066 imageTarget->addTargetSibling(this);
67}
68
Jamie Madill4928b7c2017-06-20 12:57:39 -040069gl::Error ImageSibling::orphanImages(const gl::Context *context)
Geoff Langa8406172015-07-21 16:53:39 -040070{
71 if (mTargetOf.get() != nullptr)
72 {
73 // Can't be a target and have sources.
74 ASSERT(mSourcesOf.empty());
75
Jamie Madill4928b7c2017-06-20 12:57:39 -040076 ANGLE_TRY(mTargetOf->orphanSibling(context, this));
77 mTargetOf.set(context, nullptr);
Geoff Langa8406172015-07-21 16:53:39 -040078 }
79 else
80 {
Jamie Madillacf2f3a2017-11-21 19:22:44 -050081 for (egl::Image *sourceImage : mSourcesOf)
Geoff Langa8406172015-07-21 16:53:39 -040082 {
Jamie Madill4928b7c2017-06-20 12:57:39 -040083 ANGLE_TRY(sourceImage->orphanSibling(context, this));
Geoff Langa8406172015-07-21 16:53:39 -040084 }
85 mSourcesOf.clear();
86 }
87
He Yunchaoacd18982017-01-04 10:46:42 +080088 return gl::NoError();
Geoff Langa8406172015-07-21 16:53:39 -040089}
90
91void ImageSibling::addImageSource(egl::Image *imageSource)
92{
93 ASSERT(imageSource != nullptr);
94 mSourcesOf.insert(imageSource);
95}
96
97void ImageSibling::removeImageSource(egl::Image *imageSource)
98{
99 ASSERT(mSourcesOf.find(imageSource) != mSourcesOf.end());
100 mSourcesOf.erase(imageSource);
101}
102
Jamie Madill05b35b22017-10-03 09:01:44 -0400103bool ImageSibling::isEGLImageTarget() const
104{
105 return (mTargetOf.get() != nullptr);
106}
107
108gl::InitState ImageSibling::sourceEGLImageInitState() const
109{
110 ASSERT(isEGLImageTarget());
111 return mTargetOf->sourceInitState();
112}
113
114void ImageSibling::setSourceEGLImageInitState(gl::InitState initState) const
115{
116 ASSERT(isEGLImageTarget());
117 mTargetOf->setInitState(initState);
118}
119
Jamie Madill76b8f462017-04-21 12:23:40 -0400120ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
Geoff Lang75359662018-04-11 01:42:27 -0400121 : label(nullptr), imageIndex(GetImageIndex(target, attribs)), source(buffer), targets()
Jamie Madill76b8f462017-04-21 12:23:40 -0400122{
Jamie Madill76b8f462017-04-21 12:23:40 -0400123}
124
Jamie Madillacf2f3a2017-11-21 19:22:44 -0500125ImageState::~ImageState()
126{
127}
128
Jamie Madill76b8f462017-04-21 12:23:40 -0400129Image::Image(rx::EGLImplFactory *factory,
Geoff Langcd7cd2a2018-07-19 11:25:54 -0400130 const gl::Context *context,
Jamie Madill76b8f462017-04-21 12:23:40 -0400131 EGLenum target,
132 ImageSibling *buffer,
133 const AttributeMap &attribs)
Geoff Langa8406172015-07-21 16:53:39 -0400134 : RefCountObject(0),
Jamie Madill76b8f462017-04-21 12:23:40 -0400135 mState(target, buffer, attribs),
Geoff Langcd7cd2a2018-07-19 11:25:54 -0400136 mImplementation(factory->createImage(mState, context, target, attribs)),
Jamie Madill05b35b22017-10-03 09:01:44 -0400137 mOrphanedAndNeedsInit(false)
Geoff Langa8406172015-07-21 16:53:39 -0400138{
139 ASSERT(mImplementation != nullptr);
140 ASSERT(buffer != nullptr);
141
Jamie Madill76b8f462017-04-21 12:23:40 -0400142 mState.source->addImageSource(this);
Geoff Langa8406172015-07-21 16:53:39 -0400143}
144
Jamie Madill71c88b32017-09-14 22:20:29 -0400145gl::Error Image::onDestroy(const gl::Context *context)
Geoff Langa8406172015-07-21 16:53:39 -0400146{
Geoff Langa8406172015-07-21 16:53:39 -0400147 // All targets should hold a ref to the egl image and it should not be deleted until there are
148 // no siblings left.
Jamie Madill76b8f462017-04-21 12:23:40 -0400149 ASSERT(mState.targets.empty());
Geoff Langa8406172015-07-21 16:53:39 -0400150
151 // Tell the source that it is no longer used by this image
Jamie Madill76b8f462017-04-21 12:23:40 -0400152 if (mState.source.get() != nullptr)
Geoff Langa8406172015-07-21 16:53:39 -0400153 {
Jamie Madill76b8f462017-04-21 12:23:40 -0400154 mState.source->removeImageSource(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400155 mState.source.set(context, nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400156 }
Jamie Madill71c88b32017-09-14 22:20:29 -0400157 return gl::NoError();
Geoff Langa8406172015-07-21 16:53:39 -0400158}
159
Jamie Madill4928b7c2017-06-20 12:57:39 -0400160Image::~Image()
161{
Jamie Madill71c88b32017-09-14 22:20:29 -0400162 SafeDelete(mImplementation);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400163}
164
Geoff Lang75359662018-04-11 01:42:27 -0400165void Image::setLabel(EGLLabelKHR label)
166{
167 mState.label = label;
168}
169
170EGLLabelKHR Image::getLabel() const
171{
172 return mState.label;
173}
174
Geoff Langa8406172015-07-21 16:53:39 -0400175void Image::addTargetSibling(ImageSibling *sibling)
176{
Jamie Madill76b8f462017-04-21 12:23:40 -0400177 mState.targets.insert(sibling);
Geoff Langa8406172015-07-21 16:53:39 -0400178}
179
Jamie Madill4928b7c2017-06-20 12:57:39 -0400180gl::Error Image::orphanSibling(const gl::Context *context, ImageSibling *sibling)
Geoff Langa8406172015-07-21 16:53:39 -0400181{
182 // notify impl
Jamie Madill4928b7c2017-06-20 12:57:39 -0400183 ANGLE_TRY(mImplementation->orphan(context, sibling));
Geoff Langa8406172015-07-21 16:53:39 -0400184
Jamie Madill76b8f462017-04-21 12:23:40 -0400185 if (mState.source.get() == sibling)
Geoff Langa8406172015-07-21 16:53:39 -0400186 {
187 // If the sibling is the source, it cannot be a target.
Jamie Madill76b8f462017-04-21 12:23:40 -0400188 ASSERT(mState.targets.find(sibling) == mState.targets.end());
Jamie Madill4928b7c2017-06-20 12:57:39 -0400189 mState.source.set(context, nullptr);
Jamie Madill05b35b22017-10-03 09:01:44 -0400190 mOrphanedAndNeedsInit =
191 (sibling->initState(mState.imageIndex) == gl::InitState::MayNeedInit);
Geoff Langa8406172015-07-21 16:53:39 -0400192 }
193 else
194 {
Jamie Madill76b8f462017-04-21 12:23:40 -0400195 mState.targets.erase(sibling);
Geoff Langa8406172015-07-21 16:53:39 -0400196 }
197
Jamie Madill76b8f462017-04-21 12:23:40 -0400198 return gl::NoError();
Geoff Langa8406172015-07-21 16:53:39 -0400199}
200
Jiawei Shaoa8802472018-05-28 11:17:47 +0800201gl::Format Image::getFormat() const
Geoff Langa8406172015-07-21 16:53:39 -0400202{
Jamie Madilld75dd262017-04-20 17:01:19 -0400203 return mState.source->getAttachmentFormat(GL_NONE, mState.imageIndex);
Geoff Langa8406172015-07-21 16:53:39 -0400204}
205
206size_t Image::getWidth() const
207{
Jamie Madilld75dd262017-04-20 17:01:19 -0400208 return mState.source->getAttachmentSize(mState.imageIndex).width;
Geoff Langa8406172015-07-21 16:53:39 -0400209}
210
211size_t Image::getHeight() const
212{
Jamie Madilld75dd262017-04-20 17:01:19 -0400213 return mState.source->getAttachmentSize(mState.imageIndex).height;
Geoff Langa8406172015-07-21 16:53:39 -0400214}
215
216size_t Image::getSamples() const
217{
Jamie Madilld75dd262017-04-20 17:01:19 -0400218 return mState.source->getAttachmentSamples(mState.imageIndex);
Geoff Langa8406172015-07-21 16:53:39 -0400219}
220
Jamie Madill76b8f462017-04-21 12:23:40 -0400221rx::ImageImpl *Image::getImplementation() const
Geoff Langa8406172015-07-21 16:53:39 -0400222{
223 return mImplementation;
224}
225
Geoff Langcd7cd2a2018-07-19 11:25:54 -0400226Error Image::initialize(const Display *display)
Geoff Langa8406172015-07-21 16:53:39 -0400227{
Geoff Langcd7cd2a2018-07-19 11:25:54 -0400228 return mImplementation->initialize(display);
Geoff Langa8406172015-07-21 16:53:39 -0400229}
Jamie Madill76b8f462017-04-21 12:23:40 -0400230
Jamie Madill05b35b22017-10-03 09:01:44 -0400231bool Image::orphaned() const
232{
233 return (mState.source.get() == nullptr);
234}
235
236gl::InitState Image::sourceInitState() const
237{
238 if (orphaned())
239 {
240 return mOrphanedAndNeedsInit ? gl::InitState::MayNeedInit : gl::InitState::Initialized;
241 }
242
243 return mState.source->initState(mState.imageIndex);
244}
245
246void Image::setInitState(gl::InitState initState)
247{
248 if (orphaned())
249 {
250 mOrphanedAndNeedsInit = false;
251 }
252
253 return mState.source->setInitState(mState.imageIndex, initState);
254}
255
Jamie Madilla3944d42016-07-22 22:13:26 -0400256} // namespace egl