blob: a99a8bbae8ce75f63888b0460c48d4becbccc622 [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"
13#include "libANGLE/angletypes.h"
Jamie Madilla3944d42016-07-22 22:13:26 -040014#include "libANGLE/formatutils.h"
Geoff Langa8406172015-07-21 16:53:39 -040015#include "libANGLE/Texture.h"
16#include "libANGLE/Renderbuffer.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 {
29 return gl::ImageIndex::MakeInvalid();
30 }
31
32 GLenum target = egl_gl::EGLImageTargetToGLTextureTarget(eglTarget);
33 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));
35
36 if (target == GL_TEXTURE_3D)
37 {
38 return gl::ImageIndex::Make3D(mip, layer);
39 }
40 else
41 {
42 ASSERT(layer == 0);
43 return gl::ImageIndex::MakeGeneric(target, mip);
44 }
45}
46} // anonymous namespace
47
Corentin Wallez51706ea2015-08-07 14:39:22 -040048ImageSibling::ImageSibling(GLuint id) : RefCountObject(id), mSourcesOf(), mTargetOf()
Geoff Langa8406172015-07-21 16:53:39 -040049{
50}
51
52ImageSibling::~ImageSibling()
53{
54 // EGL images should hold a ref to their targets and siblings, a Texture should not be deletable
55 // while it is attached to an EGL image.
Jamie Madill4928b7c2017-06-20 12:57:39 -040056 // Child class should orphan images before destruction.
Geoff Langa8406172015-07-21 16:53:39 -040057 ASSERT(mSourcesOf.empty());
Jamie Madill4928b7c2017-06-20 12:57:39 -040058 ASSERT(mTargetOf.get() == nullptr);
Geoff Langa8406172015-07-21 16:53:39 -040059}
60
Jamie Madill4928b7c2017-06-20 12:57:39 -040061void ImageSibling::setTargetImage(const gl::Context *context, egl::Image *imageTarget)
Geoff Langa8406172015-07-21 16:53:39 -040062{
63 ASSERT(imageTarget != nullptr);
Jamie Madill4928b7c2017-06-20 12:57:39 -040064 mTargetOf.set(context, imageTarget);
Geoff Langa8406172015-07-21 16:53:39 -040065 imageTarget->addTargetSibling(this);
66}
67
Jamie Madill4928b7c2017-06-20 12:57:39 -040068gl::Error ImageSibling::orphanImages(const gl::Context *context)
Geoff Langa8406172015-07-21 16:53:39 -040069{
70 if (mTargetOf.get() != nullptr)
71 {
72 // Can't be a target and have sources.
73 ASSERT(mSourcesOf.empty());
74
Jamie Madill4928b7c2017-06-20 12:57:39 -040075 ANGLE_TRY(mTargetOf->orphanSibling(context, this));
76 mTargetOf.set(context, nullptr);
Geoff Langa8406172015-07-21 16:53:39 -040077 }
78 else
79 {
80 for (auto &sourceImage : mSourcesOf)
81 {
Jamie Madill4928b7c2017-06-20 12:57:39 -040082 ANGLE_TRY(sourceImage->orphanSibling(context, this));
Geoff Langa8406172015-07-21 16:53:39 -040083 }
84 mSourcesOf.clear();
85 }
86
He Yunchaoacd18982017-01-04 10:46:42 +080087 return gl::NoError();
Geoff Langa8406172015-07-21 16:53:39 -040088}
89
90void ImageSibling::addImageSource(egl::Image *imageSource)
91{
92 ASSERT(imageSource != nullptr);
93 mSourcesOf.insert(imageSource);
94}
95
96void ImageSibling::removeImageSource(egl::Image *imageSource)
97{
98 ASSERT(mSourcesOf.find(imageSource) != mSourcesOf.end());
99 mSourcesOf.erase(imageSource);
100}
101
Jamie Madill76b8f462017-04-21 12:23:40 -0400102ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
Jamie Madill4928b7c2017-06-20 12:57:39 -0400103 : imageIndex(GetImageIndex(target, attribs)), source(buffer), targets()
Jamie Madill76b8f462017-04-21 12:23:40 -0400104{
Jamie Madill76b8f462017-04-21 12:23:40 -0400105}
106
107Image::Image(rx::EGLImplFactory *factory,
108 EGLenum target,
109 ImageSibling *buffer,
110 const AttributeMap &attribs)
Geoff Langa8406172015-07-21 16:53:39 -0400111 : RefCountObject(0),
Jamie Madill76b8f462017-04-21 12:23:40 -0400112 mState(target, buffer, attribs),
Jamie Madilld75dd262017-04-20 17:01:19 -0400113 mImplementation(factory->createImage(mState, target, attribs))
Geoff Langa8406172015-07-21 16:53:39 -0400114{
115 ASSERT(mImplementation != nullptr);
116 ASSERT(buffer != nullptr);
117
Jamie Madill76b8f462017-04-21 12:23:40 -0400118 mState.source->addImageSource(this);
Geoff Langa8406172015-07-21 16:53:39 -0400119}
120
Jamie Madill4928b7c2017-06-20 12:57:39 -0400121void Image::onDestroy(const gl::Context *context)
Geoff Langa8406172015-07-21 16:53:39 -0400122{
123 SafeDelete(mImplementation);
124
125 // All targets should hold a ref to the egl image and it should not be deleted until there are
126 // no siblings left.
Jamie Madill76b8f462017-04-21 12:23:40 -0400127 ASSERT(mState.targets.empty());
Geoff Langa8406172015-07-21 16:53:39 -0400128
129 // Tell the source that it is no longer used by this image
Jamie Madill76b8f462017-04-21 12:23:40 -0400130 if (mState.source.get() != nullptr)
Geoff Langa8406172015-07-21 16:53:39 -0400131 {
Jamie Madill76b8f462017-04-21 12:23:40 -0400132 mState.source->removeImageSource(this);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400133 mState.source.set(context, nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400134 }
135}
136
Jamie Madill4928b7c2017-06-20 12:57:39 -0400137Image::~Image()
138{
139 ASSERT(!mImplementation);
140}
141
Geoff Langa8406172015-07-21 16:53:39 -0400142void Image::addTargetSibling(ImageSibling *sibling)
143{
Jamie Madill76b8f462017-04-21 12:23:40 -0400144 mState.targets.insert(sibling);
Geoff Langa8406172015-07-21 16:53:39 -0400145}
146
Jamie Madill4928b7c2017-06-20 12:57:39 -0400147gl::Error Image::orphanSibling(const gl::Context *context, ImageSibling *sibling)
Geoff Langa8406172015-07-21 16:53:39 -0400148{
149 // notify impl
Jamie Madill4928b7c2017-06-20 12:57:39 -0400150 ANGLE_TRY(mImplementation->orphan(context, sibling));
Geoff Langa8406172015-07-21 16:53:39 -0400151
Jamie Madill76b8f462017-04-21 12:23:40 -0400152 if (mState.source.get() == sibling)
Geoff Langa8406172015-07-21 16:53:39 -0400153 {
154 // If the sibling is the source, it cannot be a target.
Jamie Madill76b8f462017-04-21 12:23:40 -0400155 ASSERT(mState.targets.find(sibling) == mState.targets.end());
Jamie Madill4928b7c2017-06-20 12:57:39 -0400156 mState.source.set(context, nullptr);
Geoff Langa8406172015-07-21 16:53:39 -0400157 }
158 else
159 {
Jamie Madill76b8f462017-04-21 12:23:40 -0400160 mState.targets.erase(sibling);
Geoff Langa8406172015-07-21 16:53:39 -0400161 }
162
Jamie Madill76b8f462017-04-21 12:23:40 -0400163 return gl::NoError();
Geoff Langa8406172015-07-21 16:53:39 -0400164}
165
Jamie Madilla3944d42016-07-22 22:13:26 -0400166const gl::Format &Image::getFormat() const
Geoff Langa8406172015-07-21 16:53:39 -0400167{
Jamie Madilld75dd262017-04-20 17:01:19 -0400168 return mState.source->getAttachmentFormat(GL_NONE, mState.imageIndex);
Geoff Langa8406172015-07-21 16:53:39 -0400169}
170
171size_t Image::getWidth() const
172{
Jamie Madilld75dd262017-04-20 17:01:19 -0400173 return mState.source->getAttachmentSize(mState.imageIndex).width;
Geoff Langa8406172015-07-21 16:53:39 -0400174}
175
176size_t Image::getHeight() const
177{
Jamie Madilld75dd262017-04-20 17:01:19 -0400178 return mState.source->getAttachmentSize(mState.imageIndex).height;
Geoff Langa8406172015-07-21 16:53:39 -0400179}
180
181size_t Image::getSamples() const
182{
Jamie Madilld75dd262017-04-20 17:01:19 -0400183 return mState.source->getAttachmentSamples(mState.imageIndex);
Geoff Langa8406172015-07-21 16:53:39 -0400184}
185
Jamie Madill76b8f462017-04-21 12:23:40 -0400186rx::ImageImpl *Image::getImplementation() const
Geoff Langa8406172015-07-21 16:53:39 -0400187{
188 return mImplementation;
189}
190
Jamie Madill76b8f462017-04-21 12:23:40 -0400191Error Image::initialize()
Geoff Langa8406172015-07-21 16:53:39 -0400192{
Jamie Madill76b8f462017-04-21 12:23:40 -0400193 return mImplementation->initialize();
Geoff Langa8406172015-07-21 16:53:39 -0400194}
Jamie Madill76b8f462017-04-21 12:23:40 -0400195
Jamie Madilla3944d42016-07-22 22:13:26 -0400196} // namespace egl