diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/Image.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/Image.cpp | 205 |
1 files changed, 129 insertions, 76 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/Image.cpp b/src/3rdparty/angle/src/libANGLE/Image.cpp index a9448e3f6c..04c757c2c4 100644 --- a/src/3rdparty/angle/src/libANGLE/Image.cpp +++ b/src/3rdparty/angle/src/libANGLE/Image.cpp @@ -11,13 +11,42 @@ #include "common/debug.h" #include "common/utilities.h" #include "libANGLE/angletypes.h" +#include "libANGLE/formatutils.h" #include "libANGLE/Texture.h" #include "libANGLE/Renderbuffer.h" +#include "libANGLE/renderer/EGLImplFactory.h" #include "libANGLE/renderer/ImageImpl.h" namespace egl { -ImageSibling::ImageSibling(GLuint id) : RefCountObject(id), mSourcesOf(), mTargetOf() + +namespace +{ +gl::ImageIndex GetImageIndex(EGLenum eglTarget, const egl::AttributeMap &attribs) +{ + if (eglTarget == EGL_GL_RENDERBUFFER) + { + return gl::ImageIndex::MakeInvalid(); + } + + GLenum target = egl_gl::EGLImageTargetToGLTextureTarget(eglTarget); + GLint mip = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0)); + GLint layer = static_cast<GLint>(attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0)); + + if (target == GL_TEXTURE_3D) + { + return gl::ImageIndex::Make3D(mip, layer); + } + else + { + ASSERT(layer == 0); + return gl::ImageIndex::MakeGeneric(target, mip); + } +} +} // anonymous namespace + +ImageSibling::ImageSibling(GLuint id) + : RefCountObject(id), FramebufferAttachmentObject(), mSourcesOf(), mTargetOf() { } @@ -25,46 +54,38 @@ ImageSibling::~ImageSibling() { // EGL images should hold a ref to their targets and siblings, a Texture should not be deletable // while it is attached to an EGL image. + // Child class should orphan images before destruction. ASSERT(mSourcesOf.empty()); - orphanImages(); + ASSERT(mTargetOf.get() == nullptr); } -void ImageSibling::setTargetImage(egl::Image *imageTarget) +void ImageSibling::setTargetImage(const gl::Context *context, egl::Image *imageTarget) { ASSERT(imageTarget != nullptr); - mTargetOf.set(imageTarget); + mTargetOf.set(context, imageTarget); imageTarget->addTargetSibling(this); } -gl::Error ImageSibling::orphanImages() +gl::Error ImageSibling::orphanImages(const gl::Context *context) { if (mTargetOf.get() != nullptr) { // Can't be a target and have sources. ASSERT(mSourcesOf.empty()); - gl::Error error = mTargetOf->orphanSibling(this); - if (error.isError()) - { - return error; - } - - mTargetOf.set(nullptr); + ANGLE_TRY(mTargetOf->orphanSibling(context, this)); + mTargetOf.set(context, nullptr); } else { - for (auto &sourceImage : mSourcesOf) + for (egl::Image *sourceImage : mSourcesOf) { - gl::Error error = sourceImage->orphanSibling(this); - if (error.isError()) - { - return error; - } + ANGLE_TRY(sourceImage->orphanSibling(context, this)); } mSourcesOf.clear(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void ImageSibling::addImageSource(egl::Image *imageSource) @@ -79,114 +100,146 @@ void ImageSibling::removeImageSource(egl::Image *imageSource) mSourcesOf.erase(imageSource); } -Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) +bool ImageSibling::isEGLImageTarget() const +{ + return (mTargetOf.get() != nullptr); +} + +gl::InitState ImageSibling::sourceEGLImageInitState() const +{ + ASSERT(isEGLImageTarget()); + return mTargetOf->sourceInitState(); +} + +void ImageSibling::setSourceEGLImageInitState(gl::InitState initState) const +{ + ASSERT(isEGLImageTarget()); + mTargetOf->setInitState(initState); +} + +ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs) + : imageIndex(GetImageIndex(target, attribs)), source(buffer), targets() +{ +} + +ImageState::~ImageState() +{ +} + +Image::Image(rx::EGLImplFactory *factory, + EGLenum target, + ImageSibling *buffer, + const AttributeMap &attribs) : RefCountObject(0), - mImplementation(impl), - mInternalFormat(GL_NONE), - mWidth(0), - mHeight(0), - mSamples(0), - mSource(), - mTargets() + mState(target, buffer, attribs), + mImplementation(factory->createImage(mState, target, attribs)), + mOrphanedAndNeedsInit(false) { ASSERT(mImplementation != nullptr); ASSERT(buffer != nullptr); - mSource.set(buffer); - mSource->addImageSource(this); - - if (IsTextureTarget(target)) - { - gl::Texture *texture = rx::GetAs<gl::Texture>(mSource.get()); - GLenum textureTarget = egl_gl::EGLImageTargetToGLTextureTarget(target); - size_t level = attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); - mInternalFormat = texture->getInternalFormat(textureTarget, level); - mWidth = texture->getWidth(textureTarget, level); - mHeight = texture->getHeight(textureTarget, level); - mSamples = 0; - } - else if (IsRenderbufferTarget(target)) - { - gl::Renderbuffer *renderbuffer = rx::GetAs<gl::Renderbuffer>(mSource.get()); - mInternalFormat = renderbuffer->getInternalFormat(); - mWidth = renderbuffer->getWidth(); - mHeight = renderbuffer->getHeight(); - mSamples = renderbuffer->getSamples(); - } - else - { - UNREACHABLE(); - } + mState.source->addImageSource(this); } -Image::~Image() +gl::Error Image::onDestroy(const gl::Context *context) { - SafeDelete(mImplementation); - // All targets should hold a ref to the egl image and it should not be deleted until there are // no siblings left. - ASSERT(mTargets.empty()); + ASSERT(mState.targets.empty()); // Tell the source that it is no longer used by this image - if (mSource.get() != nullptr) + if (mState.source.get() != nullptr) { - mSource->removeImageSource(this); - mSource.set(nullptr); + mState.source->removeImageSource(this); + mState.source.set(context, nullptr); } + return gl::NoError(); +} + +Image::~Image() +{ + SafeDelete(mImplementation); } void Image::addTargetSibling(ImageSibling *sibling) { - mTargets.insert(sibling); + mState.targets.insert(sibling); } -gl::Error Image::orphanSibling(ImageSibling *sibling) +gl::Error Image::orphanSibling(const gl::Context *context, ImageSibling *sibling) { // notify impl - gl::Error error = mImplementation->orphan(sibling); + ANGLE_TRY(mImplementation->orphan(context, sibling)); - if (mSource.get() == sibling) + if (mState.source.get() == sibling) { // If the sibling is the source, it cannot be a target. - ASSERT(mTargets.find(sibling) == mTargets.end()); - - mSource.set(nullptr); + ASSERT(mState.targets.find(sibling) == mState.targets.end()); + mState.source.set(context, nullptr); + mOrphanedAndNeedsInit = + (sibling->initState(mState.imageIndex) == gl::InitState::MayNeedInit); } else { - mTargets.erase(sibling); + mState.targets.erase(sibling); } - return error; + return gl::NoError(); } -GLenum Image::getInternalFormat() const +const gl::Format &Image::getFormat() const { - return mInternalFormat; + return mState.source->getAttachmentFormat(GL_NONE, mState.imageIndex); } size_t Image::getWidth() const { - return mWidth; + return mState.source->getAttachmentSize(mState.imageIndex).width; } size_t Image::getHeight() const { - return mHeight; + return mState.source->getAttachmentSize(mState.imageIndex).height; } size_t Image::getSamples() const { - return mSamples; + return mState.source->getAttachmentSamples(mState.imageIndex); } -rx::ImageImpl *Image::getImplementation() +rx::ImageImpl *Image::getImplementation() const { return mImplementation; } -const rx::ImageImpl *Image::getImplementation() const +Error Image::initialize() { - return mImplementation; + return mImplementation->initialize(); +} + +bool Image::orphaned() const +{ + return (mState.source.get() == nullptr); +} + +gl::InitState Image::sourceInitState() const +{ + if (orphaned()) + { + return mOrphanedAndNeedsInit ? gl::InitState::MayNeedInit : gl::InitState::Initialized; + } + + return mState.source->initState(mState.imageIndex); } + +void Image::setInitState(gl::InitState initState) +{ + if (orphaned()) + { + mOrphanedAndNeedsInit = false; + } + + return mState.source->setInitState(mState.imageIndex, initState); } + +} // namespace egl |