Use a shared state for egl::Image.
This allows us to stop duplicating some information in the impl.
BUG=angleproject:1635
Change-Id: If8f7d2418571c3254729f48c463814ec18ed2644
Reviewed-on: https://chromium-review.googlesource.com/469153
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Image.cpp b/src/libANGLE/Image.cpp
index 718480b..1a39304 100644
--- a/src/libANGLE/Image.cpp
+++ b/src/libANGLE/Image.cpp
@@ -14,10 +14,37 @@
#include "libANGLE/formatutils.h"
#include "libANGLE/Texture.h"
#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/renderer/ImageImpl.h"
namespace egl
{
+
+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), mSourcesOf(), mTargetOf()
{
}
@@ -44,23 +71,14 @@
// Can't be a target and have sources.
ASSERT(mSourcesOf.empty());
- gl::Error error = mTargetOf->orphanSibling(this);
- if (error.isError())
- {
- return error;
- }
-
+ ANGLE_TRY(mTargetOf->orphanSibling(this));
mTargetOf.set(nullptr);
}
else
{
for (auto &sourceImage : mSourcesOf)
{
- gl::Error error = sourceImage->orphanSibling(this);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(sourceImage->orphanSibling(this));
}
mSourcesOf.clear();
}
@@ -80,25 +98,32 @@
mSourcesOf.erase(imageSource);
}
-Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
+ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs)
+ : imageIndex(GetImageIndex(target, attribs)), source(), targets()
+{
+ source.set(buffer);
+}
+
+Image::Image(rx::EGLImplFactory *factory,
+ EGLenum target,
+ ImageSibling *buffer,
+ const AttributeMap &attribs)
: RefCountObject(0),
- mImplementation(impl),
+ mState(target, buffer, attribs),
+ mImplementation(factory->createImage(mState, target, attribs)),
mFormat(gl::Format::Invalid()),
mWidth(0),
mHeight(0),
- mSamples(0),
- mSource(),
- mTargets()
+ mSamples(0)
{
ASSERT(mImplementation != nullptr);
ASSERT(buffer != nullptr);
- mSource.set(buffer);
- mSource->addImageSource(this);
+ mState.source->addImageSource(this);
if (IsTextureTarget(target))
{
- gl::Texture *texture = rx::GetAs<gl::Texture>(mSource.get());
+ gl::Texture *texture = rx::GetAs<gl::Texture>(mState.source.get());
GLenum textureTarget = egl_gl::EGLImageTargetToGLTextureTarget(target);
size_t level = attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0);
mFormat = texture->getFormat(textureTarget, level);
@@ -108,7 +133,7 @@
}
else if (IsRenderbufferTarget(target))
{
- gl::Renderbuffer *renderbuffer = rx::GetAs<gl::Renderbuffer>(mSource.get());
+ gl::Renderbuffer *renderbuffer = rx::GetAs<gl::Renderbuffer>(mState.source.get());
mFormat = renderbuffer->getFormat();
mWidth = renderbuffer->getWidth();
mHeight = renderbuffer->getHeight();
@@ -126,39 +151,38 @@
// 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(nullptr);
}
}
void Image::addTargetSibling(ImageSibling *sibling)
{
- mTargets.insert(sibling);
+ mState.targets.insert(sibling);
}
gl::Error Image::orphanSibling(ImageSibling *sibling)
{
// notify impl
- gl::Error error = mImplementation->orphan(sibling);
+ ANGLE_TRY(mImplementation->orphan(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(nullptr);
}
else
{
- mTargets.erase(sibling);
+ mState.targets.erase(sibling);
}
- return error;
+ return gl::NoError();
}
const gl::Format &Image::getFormat() const
@@ -181,13 +205,14 @@
return mSamples;
}
-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();
}
+
} // namespace egl