Commit 76b8f469 by Jamie Madill Committed by Commit Bot

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: 's avatarCorentin Wallez <cwallez@chromium.org>
parent f6b986c8
...@@ -635,12 +635,10 @@ Error Display::createImage(gl::Context *context, ...@@ -635,12 +635,10 @@ Error Display::createImage(gl::Context *context,
} }
ASSERT(sibling != nullptr); ASSERT(sibling != nullptr);
rx::ImageImpl *imageImpl = mImplementation->createImage(target, sibling, attribs); std::unique_ptr<Image> imagePtr(new Image(mImplementation, target, sibling, attribs));
ASSERT(imageImpl != nullptr); ANGLE_TRY(imagePtr->initialize());
ANGLE_TRY(imageImpl->initialize()); Image *image = imagePtr.release();
Image *image = new Image(imageImpl, target, sibling, attribs);
ASSERT(outImage != nullptr); ASSERT(outImage != nullptr);
*outImage = image; *outImage = image;
...@@ -649,7 +647,7 @@ Error Display::createImage(gl::Context *context, ...@@ -649,7 +647,7 @@ Error Display::createImage(gl::Context *context,
image->addRef(); image->addRef();
mImageSet.insert(image); mImageSet.insert(image);
return egl::Error(EGL_SUCCESS); return egl::NoError();
} }
Error Display::createStream(const AttributeMap &attribs, Stream **outStream) Error Display::createStream(const AttributeMap &attribs, Stream **outStream)
......
...@@ -14,10 +14,37 @@ ...@@ -14,10 +14,37 @@
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
#include "libANGLE/Texture.h" #include "libANGLE/Texture.h"
#include "libANGLE/Renderbuffer.h" #include "libANGLE/Renderbuffer.h"
#include "libANGLE/renderer/EGLImplFactory.h"
#include "libANGLE/renderer/ImageImpl.h" #include "libANGLE/renderer/ImageImpl.h"
namespace egl 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() ImageSibling::ImageSibling(GLuint id) : RefCountObject(id), mSourcesOf(), mTargetOf()
{ {
} }
...@@ -44,23 +71,14 @@ gl::Error ImageSibling::orphanImages() ...@@ -44,23 +71,14 @@ gl::Error ImageSibling::orphanImages()
// Can't be a target and have sources. // Can't be a target and have sources.
ASSERT(mSourcesOf.empty()); ASSERT(mSourcesOf.empty());
gl::Error error = mTargetOf->orphanSibling(this); ANGLE_TRY(mTargetOf->orphanSibling(this));
if (error.isError())
{
return error;
}
mTargetOf.set(nullptr); mTargetOf.set(nullptr);
} }
else else
{ {
for (auto &sourceImage : mSourcesOf) for (auto &sourceImage : mSourcesOf)
{ {
gl::Error error = sourceImage->orphanSibling(this); ANGLE_TRY(sourceImage->orphanSibling(this));
if (error.isError())
{
return error;
}
} }
mSourcesOf.clear(); mSourcesOf.clear();
} }
...@@ -80,25 +98,32 @@ void ImageSibling::removeImageSource(egl::Image *imageSource) ...@@ -80,25 +98,32 @@ void ImageSibling::removeImageSource(egl::Image *imageSource)
mSourcesOf.erase(imageSource); 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), : RefCountObject(0),
mImplementation(impl), mState(target, buffer, attribs),
mImplementation(factory->createImage(mState, target, attribs)),
mFormat(gl::Format::Invalid()), mFormat(gl::Format::Invalid()),
mWidth(0), mWidth(0),
mHeight(0), mHeight(0),
mSamples(0), mSamples(0)
mSource(),
mTargets()
{ {
ASSERT(mImplementation != nullptr); ASSERT(mImplementation != nullptr);
ASSERT(buffer != nullptr); ASSERT(buffer != nullptr);
mSource.set(buffer); mState.source->addImageSource(this);
mSource->addImageSource(this);
if (IsTextureTarget(target)) 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); GLenum textureTarget = egl_gl::EGLImageTargetToGLTextureTarget(target);
size_t level = attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); size_t level = attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0);
mFormat = texture->getFormat(textureTarget, level); mFormat = texture->getFormat(textureTarget, level);
...@@ -108,7 +133,7 @@ Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const At ...@@ -108,7 +133,7 @@ Image::Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const At
} }
else if (IsRenderbufferTarget(target)) 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(); mFormat = renderbuffer->getFormat();
mWidth = renderbuffer->getWidth(); mWidth = renderbuffer->getWidth();
mHeight = renderbuffer->getHeight(); mHeight = renderbuffer->getHeight();
...@@ -126,39 +151,38 @@ Image::~Image() ...@@ -126,39 +151,38 @@ Image::~Image()
// All targets should hold a ref to the egl image and it should not be deleted until there are // All targets should hold a ref to the egl image and it should not be deleted until there are
// no siblings left. // no siblings left.
ASSERT(mTargets.empty()); ASSERT(mState.targets.empty());
// Tell the source that it is no longer used by this image // Tell the source that it is no longer used by this image
if (mSource.get() != nullptr) if (mState.source.get() != nullptr)
{ {
mSource->removeImageSource(this); mState.source->removeImageSource(this);
mSource.set(nullptr); mState.source.set(nullptr);
} }
} }
void Image::addTargetSibling(ImageSibling *sibling) void Image::addTargetSibling(ImageSibling *sibling)
{ {
mTargets.insert(sibling); mState.targets.insert(sibling);
} }
gl::Error Image::orphanSibling(ImageSibling *sibling) gl::Error Image::orphanSibling(ImageSibling *sibling)
{ {
// notify impl // 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. // If the sibling is the source, it cannot be a target.
ASSERT(mTargets.find(sibling) == mTargets.end()); ASSERT(mState.targets.find(sibling) == mState.targets.end());
mState.source.set(nullptr);
mSource.set(nullptr);
} }
else else
{ {
mTargets.erase(sibling); mState.targets.erase(sibling);
} }
return error; return gl::NoError();
} }
const gl::Format &Image::getFormat() const const gl::Format &Image::getFormat() const
...@@ -181,13 +205,14 @@ size_t Image::getSamples() const ...@@ -181,13 +205,14 @@ size_t Image::getSamples() const
return mSamples; return mSamples;
} }
rx::ImageImpl *Image::getImplementation() rx::ImageImpl *Image::getImplementation() const
{ {
return mImplementation; return mImplementation;
} }
const rx::ImageImpl *Image::getImplementation() const Error Image::initialize()
{ {
return mImplementation; return mImplementation->initialize();
} }
} // namespace egl } // namespace egl
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/AttributeMap.h" #include "libANGLE/AttributeMap.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/ImageIndex.h"
#include "libANGLE/RefCountObject.h" #include "libANGLE/RefCountObject.h"
#include "libANGLE/formatutils.h" #include "libANGLE/formatutils.h"
...@@ -19,6 +20,7 @@ ...@@ -19,6 +20,7 @@
namespace rx namespace rx
{ {
class EGLImplFactory;
class ImageImpl; class ImageImpl;
} }
...@@ -52,10 +54,22 @@ class ImageSibling : public RefCountObject ...@@ -52,10 +54,22 @@ class ImageSibling : public RefCountObject
BindingPointer<Image> mTargetOf; BindingPointer<Image> mTargetOf;
}; };
struct ImageState : angle::NonCopyable
{
ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap &attribs);
gl::ImageIndex imageIndex;
BindingPointer<ImageSibling> source;
std::set<ImageSibling *> targets;
};
class Image final : public RefCountObject class Image final : public RefCountObject
{ {
public: public:
Image(rx::ImageImpl *impl, EGLenum target, ImageSibling *buffer, const AttributeMap &attribs); Image(rx::EGLImplFactory *factory,
EGLenum target,
ImageSibling *buffer,
const AttributeMap &attribs);
~Image(); ~Image();
const gl::Format &getFormat() const; const gl::Format &getFormat() const;
...@@ -63,8 +77,9 @@ class Image final : public RefCountObject ...@@ -63,8 +77,9 @@ class Image final : public RefCountObject
size_t getHeight() const; size_t getHeight() const;
size_t getSamples() const; size_t getSamples() const;
rx::ImageImpl *getImplementation(); Error initialize();
const rx::ImageImpl *getImplementation() const;
rx::ImageImpl *getImplementation() const;
private: private:
friend class ImageSibling; friend class ImageSibling;
...@@ -77,16 +92,15 @@ class Image final : public RefCountObject ...@@ -77,16 +92,15 @@ class Image final : public RefCountObject
// been respecified and state tracking should be updated. // been respecified and state tracking should be updated.
gl::Error orphanSibling(ImageSibling *sibling); gl::Error orphanSibling(ImageSibling *sibling);
ImageState mState;
rx::ImageImpl *mImplementation; rx::ImageImpl *mImplementation;
gl::Format mFormat; gl::Format mFormat;
size_t mWidth; size_t mWidth;
size_t mHeight; size_t mHeight;
size_t mSamples; size_t mSamples;
BindingPointer<ImageSibling> mSource;
std::set<ImageSibling *> mTargets;
}; };
} } // namespace egl
#endif // LIBANGLE_IMAGE_H_ #endif // LIBANGLE_IMAGE_H_
...@@ -22,24 +22,35 @@ using ::testing::Return; ...@@ -22,24 +22,35 @@ using ::testing::Return;
namespace angle namespace angle
{ {
ACTION(CreateMockImageImpl)
{
return new rx::MockImageImpl(arg0, arg1, arg2);
}
// Verify ref counts are maintained between images and their siblings when objects are deleted // Verify ref counts are maintained between images and their siblings when objects are deleted
TEST(ImageTest, RefCounting) TEST(ImageTest, RefCounting)
{ {
NiceMock<rx::MockGLFactory> mockFactory; NiceMock<rx::MockGLFactory> mockGLFactory;
NiceMock<rx::MockEGLFactory> mockEGLFactory;
// Create a texture and an EGL image that uses the texture as its source // Create a texture and an EGL image that uses the texture as its source
rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl(); rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl();
EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl)); EXPECT_CALL(mockGLFactory, createTexture(_)).WillOnce(Return(textureImpl));
gl::Texture *texture = new gl::Texture(&mockFactory, 1, GL_TEXTURE_2D); gl::Texture *texture = new gl::Texture(&mockGLFactory, 1, GL_TEXTURE_2D);
texture->addRef(); texture->addRef();
rx::MockImageImpl *imageImpl = new rx::MockImageImpl(); EXPECT_CALL(mockEGLFactory, createImage(_, _, _))
egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap()); .WillOnce(CreateMockImageImpl())
.RetiresOnSaturation();
egl::Image *image =
new egl::Image(&mockEGLFactory, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap());
image->addRef(); image->addRef();
// Verify that the image added a ref to the texture and the texture has not added a ref to the // Verify that the image added a ref to the texture and the texture has not added a ref to the
// image // image
EXPECT_EQ(texture->getRefCount(), 2u); EXPECT_EQ(2u, texture->getRefCount());
EXPECT_EQ(image->getRefCount(), 1u); EXPECT_EQ(1u, image->getRefCount());
// Create a renderbuffer and set it as a target of the EGL image // Create a renderbuffer and set it as a target of the EGL image
rx::MockRenderbufferImpl *renderbufferImpl = new rx::MockRenderbufferImpl(); rx::MockRenderbufferImpl *renderbufferImpl = new rx::MockRenderbufferImpl();
...@@ -53,25 +64,26 @@ TEST(ImageTest, RefCounting) ...@@ -53,25 +64,26 @@ TEST(ImageTest, RefCounting)
// Verify that the renderbuffer added a ref to the image and the image did not add a ref to // Verify that the renderbuffer added a ref to the image and the image did not add a ref to
// the renderbuffer // the renderbuffer
EXPECT_EQ(texture->getRefCount(), 2u); EXPECT_EQ(2u, texture->getRefCount());
EXPECT_EQ(image->getRefCount(), 2u); EXPECT_EQ(2u, image->getRefCount());
EXPECT_EQ(renderbuffer->getRefCount(), 1u); EXPECT_EQ(1u, renderbuffer->getRefCount());
// Simulate deletion of the texture and verify that it still exists because the image holds a // Simulate deletion of the texture and verify that it still exists because the image holds a
// ref // ref
texture->release(); texture->release();
EXPECT_EQ(texture->getRefCount(), 1u); EXPECT_EQ(1u, texture->getRefCount());
EXPECT_EQ(image->getRefCount(), 2u); EXPECT_EQ(2u, image->getRefCount());
EXPECT_EQ(renderbuffer->getRefCount(), 1u); EXPECT_EQ(1u, renderbuffer->getRefCount());
// Simulate deletion of the image and verify that it still exists because the renderbuffer holds // Simulate deletion of the image and verify that it still exists because the renderbuffer holds
// a ref // a ref
image->release(); image->release();
EXPECT_EQ(texture->getRefCount(), 1u); EXPECT_EQ(1u, texture->getRefCount());
EXPECT_EQ(image->getRefCount(), 1u); EXPECT_EQ(1u, image->getRefCount());
EXPECT_EQ(renderbuffer->getRefCount(), 1u); EXPECT_EQ(1u, renderbuffer->getRefCount());
// Simulate deletion of the renderbuffer and verify that the deletion cascades to all objects // Simulate deletion of the renderbuffer and verify that the deletion cascades to all objects
rx::MockImageImpl *imageImpl = static_cast<rx::MockImageImpl *>(image->getImplementation());
EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation(); EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation();
EXPECT_CALL(*imageImpl, orphan(_)).WillOnce(Return(gl::NoError())).RetiresOnSaturation(); EXPECT_CALL(*imageImpl, orphan(_)).WillOnce(Return(gl::NoError())).RetiresOnSaturation();
...@@ -84,11 +96,13 @@ TEST(ImageTest, RefCounting) ...@@ -84,11 +96,13 @@ TEST(ImageTest, RefCounting)
// Verify that respecifiying textures releases references to the Image. // Verify that respecifiying textures releases references to the Image.
TEST(ImageTest, RespecificationReleasesReferences) TEST(ImageTest, RespecificationReleasesReferences)
{ {
NiceMock<rx::MockGLFactory> mockFactory; NiceMock<rx::MockGLFactory> mockGLFactory;
NiceMock<rx::MockEGLFactory> mockEGLFactory;
// Create a texture and an EGL image that uses the texture as its source // Create a texture and an EGL image that uses the texture as its source
rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl(); rx::MockTextureImpl *textureImpl = new rx::MockTextureImpl();
EXPECT_CALL(mockFactory, createTexture(_)).WillOnce(Return(textureImpl)); EXPECT_CALL(mockGLFactory, createTexture(_)).WillOnce(Return(textureImpl));
gl::Texture *texture = new gl::Texture(&mockFactory, 1, GL_TEXTURE_2D); gl::Texture *texture = new gl::Texture(&mockGLFactory, 1, GL_TEXTURE_2D);
texture->addRef(); texture->addRef();
gl::PixelUnpackState defaultUnpackState; gl::PixelUnpackState defaultUnpackState;
...@@ -99,16 +113,21 @@ TEST(ImageTest, RespecificationReleasesReferences) ...@@ -99,16 +113,21 @@ TEST(ImageTest, RespecificationReleasesReferences)
texture->setImage(nullptr, defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), texture->setImage(nullptr, defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1),
GL_RGBA, GL_UNSIGNED_BYTE, nullptr); GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
rx::MockImageImpl *imageImpl = new rx::MockImageImpl(); EXPECT_CALL(mockEGLFactory, createImage(_, _, _))
egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap()); .WillOnce(CreateMockImageImpl())
.RetiresOnSaturation();
egl::Image *image =
new egl::Image(&mockEGLFactory, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap());
image->addRef(); image->addRef();
// Verify that the image added a ref to the texture and the texture has not added a ref to the // Verify that the image added a ref to the texture and the texture has not added a ref to the
// image // image
EXPECT_EQ(texture->getRefCount(), 2u); EXPECT_EQ(2u, texture->getRefCount());
EXPECT_EQ(image->getRefCount(), 1u); EXPECT_EQ(1u, image->getRefCount());
// Respecify the texture and verify that the image releases its reference // Respecify the texture and verify that the image releases its reference
rx::MockImageImpl *imageImpl = static_cast<rx::MockImageImpl *>(image->getImplementation());
EXPECT_CALL(*imageImpl, orphan(_)).WillOnce(Return(gl::NoError())).RetiresOnSaturation(); EXPECT_CALL(*imageImpl, orphan(_)).WillOnce(Return(gl::NoError())).RetiresOnSaturation();
EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _, _)) EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _, _))
.WillOnce(Return(gl::NoError())) .WillOnce(Return(gl::NoError()))
...@@ -117,17 +136,17 @@ TEST(ImageTest, RespecificationReleasesReferences) ...@@ -117,17 +136,17 @@ TEST(ImageTest, RespecificationReleasesReferences)
texture->setImage(nullptr, defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), texture->setImage(nullptr, defaultUnpackState, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1),
GL_RGBA, GL_UNSIGNED_BYTE, nullptr); GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
EXPECT_EQ(texture->getRefCount(), 1u); EXPECT_EQ(1u, texture->getRefCount());
EXPECT_EQ(image->getRefCount(), 1u); EXPECT_EQ(1u, image->getRefCount());
// Delete the texture and verify that the image still exists // Delete the texture and verify that the image still exists
EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation(); EXPECT_CALL(*textureImpl, destructor()).Times(1).RetiresOnSaturation();
texture->release(); texture->release();
EXPECT_EQ(image->getRefCount(), 1u); EXPECT_EQ(1u, image->getRefCount());
// Delete the image // Delete the image
EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation(); EXPECT_CALL(*imageImpl, destructor()).Times(1).RetiresOnSaturation();
image->release(); image->release();
} }
} } // namespace angle
...@@ -17,6 +17,7 @@ namespace egl ...@@ -17,6 +17,7 @@ namespace egl
class AttributeMap; class AttributeMap;
struct Config; struct Config;
class ImageSibling; class ImageSibling;
struct ImageState;
struct SurfaceState; struct SurfaceState;
} }
...@@ -51,8 +52,8 @@ class EGLImplFactory : angle::NonCopyable ...@@ -51,8 +52,8 @@ class EGLImplFactory : angle::NonCopyable
NativePixmapType nativePixmap, NativePixmapType nativePixmap,
const egl::AttributeMap &attribs) = 0; const egl::AttributeMap &attribs) = 0;
virtual ImageImpl *createImage(EGLenum target, virtual ImageImpl *createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) = 0; const egl::AttributeMap &attribs) = 0;
virtual ContextImpl *createContext(const gl::ContextState &state) = 0; virtual ContextImpl *createContext(const gl::ContextState &state) = 0;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
namespace egl namespace egl
{ {
class ImageSibling; class ImageSibling;
struct ImageState;
} }
namespace rx namespace rx
...@@ -22,11 +23,15 @@ namespace rx ...@@ -22,11 +23,15 @@ namespace rx
class ImageImpl : angle::NonCopyable class ImageImpl : angle::NonCopyable
{ {
public: public:
ImageImpl(const egl::ImageState &state) : mState(state) {}
virtual ~ImageImpl() {} virtual ~ImageImpl() {}
virtual egl::Error initialize() = 0; virtual egl::Error initialize() = 0;
virtual gl::Error orphan(egl::ImageSibling *sibling) = 0; virtual gl::Error orphan(egl::ImageSibling *sibling) = 0;
protected:
const egl::ImageState &mState;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_IMAGEIMPL_H_ #endif // LIBANGLE_RENDERER_IMAGEIMPL_H_
...@@ -18,11 +18,17 @@ namespace rx ...@@ -18,11 +18,17 @@ namespace rx
class MockImageImpl : public ImageImpl class MockImageImpl : public ImageImpl
{ {
public: public:
MockImageImpl(const egl::ImageState &state,
EGLenum /*target*/,
const egl::AttributeMap & /*attribs*/)
: ImageImpl(state)
{
}
virtual ~MockImageImpl() { destructor(); } virtual ~MockImageImpl() { destructor(); }
MOCK_METHOD0(initialize, egl::Error(void)); MOCK_METHOD0(initialize, egl::Error(void));
MOCK_METHOD1(orphan, gl::Error(egl::ImageSibling *)); MOCK_METHOD1(orphan, gl::Error(egl::ImageSibling *));
MOCK_METHOD0(destructor, void()); MOCK_METHOD0(destructor, void());
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_IMAGEIMPLMOCK_H_ #endif // LIBANGLE_RENDERER_IMAGEIMPLMOCK_H_
...@@ -187,11 +187,11 @@ SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state, ...@@ -187,11 +187,11 @@ SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state,
return nullptr; return nullptr;
} }
ImageImpl *DisplayD3D::createImage(EGLenum target, ImageImpl *DisplayD3D::createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
return new EGLImageD3D(mRenderer, target, buffer, attribs); return new EGLImageD3D(state, target, attribs, mRenderer);
} }
egl::Error DisplayD3D::getDevice(DeviceImpl **device) egl::Error DisplayD3D::getDevice(DeviceImpl **device)
......
...@@ -38,8 +38,8 @@ class DisplayD3D : public DisplayImpl ...@@ -38,8 +38,8 @@ class DisplayD3D : public DisplayImpl
NativePixmapType nativePixmap, NativePixmapType nativePixmap,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ImageImpl *createImage(EGLenum target, ImageImpl *createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ContextImpl *createContext(const gl::ContextState &state) override; ContextImpl *createContext(const gl::ContextState &state) override;
......
...@@ -22,42 +22,23 @@ ...@@ -22,42 +22,23 @@
namespace rx namespace rx
{ {
static gl::ImageIndex GetImageIndex(GLenum target, size_t mip, size_t layer)
{
if (target == GL_TEXTURE_3D)
{
return gl::ImageIndex::Make3D(static_cast<GLint>(mip), static_cast<GLint>(layer));
}
else
{
ASSERT(layer == 0);
return gl::ImageIndex::MakeGeneric(target, static_cast<GLint>(mip));
}
}
EGLImageD3D::EGLImageD3D(RendererD3D *renderer, EGLImageD3D::EGLImageD3D(const egl::ImageState &state,
EGLenum target, EGLenum target,
egl::ImageSibling *buffer, const egl::AttributeMap &attribs,
const egl::AttributeMap &attribs) RendererD3D *renderer)
: mRenderer(renderer), : ImageImpl(state), mRenderer(renderer), mAttachmentBuffer(nullptr), mRenderTarget(nullptr)
mBuffer(buffer),
mImageIndex(gl::ImageIndex::MakeInvalid()),
mAttachmentBuffer(nullptr),
mRenderTarget(nullptr)
{ {
ASSERT(renderer != nullptr); ASSERT(renderer != nullptr);
ASSERT(buffer != nullptr);
if (egl::IsTextureTarget(target)) if (egl::IsTextureTarget(target))
{ {
mAttachmentBuffer = GetImplAs<TextureD3D>(GetAs<gl::Texture>(buffer)); mAttachmentBuffer = GetImplAs<TextureD3D>(GetAs<gl::Texture>(mState.source.get()));
mImageIndex = GetImageIndex(egl_gl::EGLImageTargetToGLTextureTarget(target),
attribs.get(EGL_GL_TEXTURE_LEVEL_KHR, 0),
attribs.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0));
} }
else if (egl::IsRenderbufferTarget(target)) else if (egl::IsRenderbufferTarget(target))
{ {
mAttachmentBuffer = GetImplAs<RenderbufferD3D>(GetAs<gl::Renderbuffer>(buffer)); mAttachmentBuffer =
GetImplAs<RenderbufferD3D>(GetAs<gl::Renderbuffer>(mState.source.get()));
} }
else else
{ {
...@@ -77,7 +58,7 @@ egl::Error EGLImageD3D::initialize() ...@@ -77,7 +58,7 @@ egl::Error EGLImageD3D::initialize()
gl::Error EGLImageD3D::orphan(egl::ImageSibling *sibling) gl::Error EGLImageD3D::orphan(egl::ImageSibling *sibling)
{ {
if (sibling == mBuffer) if (sibling == mState.source.get())
{ {
ANGLE_TRY(copyToLocalRendertarget()); ANGLE_TRY(copyToLocalRendertarget());
} }
...@@ -90,7 +71,7 @@ gl::Error EGLImageD3D::getRenderTarget(RenderTargetD3D **outRT) const ...@@ -90,7 +71,7 @@ gl::Error EGLImageD3D::getRenderTarget(RenderTargetD3D **outRT) const
if (mAttachmentBuffer) if (mAttachmentBuffer)
{ {
FramebufferAttachmentRenderTarget *rt = nullptr; FramebufferAttachmentRenderTarget *rt = nullptr;
ANGLE_TRY(mAttachmentBuffer->getAttachmentRenderTarget(GL_NONE, mImageIndex, &rt)); ANGLE_TRY(mAttachmentBuffer->getAttachmentRenderTarget(GL_NONE, mState.imageIndex, &rt));
*outRT = static_cast<RenderTargetD3D *>(rt); *outRT = static_cast<RenderTargetD3D *>(rt);
return gl::NoError(); return gl::NoError();
} }
...@@ -104,7 +85,7 @@ gl::Error EGLImageD3D::getRenderTarget(RenderTargetD3D **outRT) const ...@@ -104,7 +85,7 @@ gl::Error EGLImageD3D::getRenderTarget(RenderTargetD3D **outRT) const
gl::Error EGLImageD3D::copyToLocalRendertarget() gl::Error EGLImageD3D::copyToLocalRendertarget()
{ {
ASSERT(mBuffer != nullptr); ASSERT(mState.source.get() != nullptr);
ASSERT(mAttachmentBuffer != nullptr); ASSERT(mAttachmentBuffer != nullptr);
ASSERT(mRenderTarget == nullptr); ASSERT(mRenderTarget == nullptr);
...@@ -115,7 +96,6 @@ gl::Error EGLImageD3D::copyToLocalRendertarget() ...@@ -115,7 +96,6 @@ gl::Error EGLImageD3D::copyToLocalRendertarget()
curRenderTarget->signalDirty(); curRenderTarget->signalDirty();
// Clear the source image buffers // Clear the source image buffers
mBuffer = nullptr;
mAttachmentBuffer = nullptr; mAttachmentBuffer = nullptr;
return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget); return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget);
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#ifndef LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ #ifndef LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_
#define LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ #define LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/renderer/ImageImpl.h" #include "libANGLE/renderer/ImageImpl.h"
namespace egl namespace egl
...@@ -19,6 +18,7 @@ class AttributeMap; ...@@ -19,6 +18,7 @@ class AttributeMap;
namespace rx namespace rx
{ {
class FramebufferAttachmentObjectImpl;
class TextureD3D; class TextureD3D;
class RenderbufferD3D; class RenderbufferD3D;
class RendererD3D; class RendererD3D;
...@@ -27,10 +27,10 @@ class RenderTargetD3D; ...@@ -27,10 +27,10 @@ class RenderTargetD3D;
class EGLImageD3D final : public ImageImpl class EGLImageD3D final : public ImageImpl
{ {
public: public:
EGLImageD3D(RendererD3D *renderer, EGLImageD3D(const egl::ImageState &state,
EGLenum target, EGLenum target,
egl::ImageSibling *buffer, const egl::AttributeMap &attribs,
const egl::AttributeMap &attribs); RendererD3D *renderer);
~EGLImageD3D() override; ~EGLImageD3D() override;
egl::Error initialize() override; egl::Error initialize() override;
...@@ -44,13 +44,10 @@ class EGLImageD3D final : public ImageImpl ...@@ -44,13 +44,10 @@ class EGLImageD3D final : public ImageImpl
RendererD3D *mRenderer; RendererD3D *mRenderer;
egl::ImageSibling *mBuffer;
gl::ImageIndex mImageIndex;
FramebufferAttachmentObjectImpl *mAttachmentBuffer; FramebufferAttachmentObjectImpl *mAttachmentBuffer;
RenderTargetD3D *mRenderTarget; RenderTargetD3D *mRenderTarget;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_ #endif // LIBANGLE_RENDERER_D3D_EGLIMAGED3D_H_
...@@ -49,8 +49,8 @@ void DisplayGL::terminate() ...@@ -49,8 +49,8 @@ void DisplayGL::terminate()
SafeDelete(mRenderer); SafeDelete(mRenderer);
} }
ImageImpl *DisplayGL::createImage(EGLenum target, ImageImpl *DisplayGL::createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -31,8 +31,8 @@ class DisplayGL : public DisplayImpl ...@@ -31,8 +31,8 @@ class DisplayGL : public DisplayImpl
egl::Error initialize(egl::Display *display) override; egl::Error initialize(egl::Display *display) override;
void terminate() override; void terminate() override;
ImageImpl *createImage(EGLenum target, ImageImpl *createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ContextImpl *createContext(const gl::ContextState &state) override; ContextImpl *createContext(const gl::ContextState &state) override;
......
...@@ -206,12 +206,12 @@ SurfaceImpl *DisplayAndroid::createPixmapSurface(const egl::SurfaceState &state, ...@@ -206,12 +206,12 @@ SurfaceImpl *DisplayAndroid::createPixmapSurface(const egl::SurfaceState &state,
return nullptr; return nullptr;
} }
ImageImpl *DisplayAndroid::createImage(EGLenum target, ImageImpl *DisplayAndroid::createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
return DisplayGL::createImage(target, buffer, attribs); return DisplayGL::createImage(state, target, attribs);
} }
template <typename T> template <typename T>
......
...@@ -40,8 +40,8 @@ class DisplayAndroid : public DisplayEGL ...@@ -40,8 +40,8 @@ class DisplayAndroid : public DisplayEGL
NativePixmapType nativePixmap, NativePixmapType nativePixmap,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ImageImpl *createImage(EGLenum target, ImageImpl *createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
egl::ConfigSet generateConfigs() override; egl::ConfigSet generateConfigs() override;
......
...@@ -164,11 +164,11 @@ SurfaceImpl *DisplayNULL::createPixmapSurface(const egl::SurfaceState &state, ...@@ -164,11 +164,11 @@ SurfaceImpl *DisplayNULL::createPixmapSurface(const egl::SurfaceState &state,
return new SurfaceNULL(state); return new SurfaceNULL(state);
} }
ImageImpl *DisplayNULL::createImage(EGLenum target, ImageImpl *DisplayNULL::createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
return new ImageNULL(); return new ImageNULL(state);
} }
ContextImpl *DisplayNULL::createContext(const gl::ContextState &state) ContextImpl *DisplayNULL::createContext(const gl::ContextState &state)
......
...@@ -60,8 +60,8 @@ class DisplayNULL : public DisplayImpl ...@@ -60,8 +60,8 @@ class DisplayNULL : public DisplayImpl
NativePixmapType nativePixmap, NativePixmapType nativePixmap,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ImageImpl *createImage(EGLenum target, ImageImpl *createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ContextImpl *createContext(const gl::ContextState &state) override; ContextImpl *createContext(const gl::ContextState &state) override;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
namespace rx namespace rx
{ {
ImageNULL::ImageNULL() : ImageImpl() ImageNULL::ImageNULL(const egl::ImageState &state) : ImageImpl(state)
{ {
} }
......
...@@ -18,7 +18,7 @@ namespace rx ...@@ -18,7 +18,7 @@ namespace rx
class ImageNULL : public ImageImpl class ImageNULL : public ImageImpl
{ {
public: public:
ImageNULL(); ImageNULL(const egl::ImageState &state);
~ImageNULL() override; ~ImageNULL() override;
egl::Error initialize() override; egl::Error initialize() override;
......
...@@ -177,8 +177,8 @@ SurfaceImpl *DisplayVk::createPixmapSurface(const egl::SurfaceState &state, ...@@ -177,8 +177,8 @@ SurfaceImpl *DisplayVk::createPixmapSurface(const egl::SurfaceState &state,
return static_cast<SurfaceImpl *>(0); return static_cast<SurfaceImpl *>(0);
} }
ImageImpl *DisplayVk::createImage(EGLenum target, ImageImpl *DisplayVk::createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -58,8 +58,8 @@ class DisplayVk : public DisplayImpl ...@@ -58,8 +58,8 @@ class DisplayVk : public DisplayImpl
NativePixmapType nativePixmap, NativePixmapType nativePixmap,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ImageImpl *createImage(EGLenum target, ImageImpl *createImage(const egl::ImageState &state,
egl::ImageSibling *buffer, EGLenum target,
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
ContextImpl *createContext(const gl::ContextState &state) override; ContextImpl *createContext(const gl::ContextState &state) override;
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
namespace rx namespace rx
{ {
ImageVk::ImageVk() : ImageImpl() ImageVk::ImageVk(const egl::ImageState &state) : ImageImpl(state)
{ {
} }
......
...@@ -18,7 +18,7 @@ namespace rx ...@@ -18,7 +18,7 @@ namespace rx
class ImageVk : public ImageImpl class ImageVk : public ImageImpl
{ {
public: public:
ImageVk(); ImageVk(const egl::ImageState &state);
~ImageVk() override; ~ImageVk() override;
egl::Error initialize() override; egl::Error initialize() override;
......
...@@ -109,7 +109,8 @@ class MockEGLFactory : public EGLImplFactory ...@@ -109,7 +109,8 @@ class MockEGLFactory : public EGLImplFactory
SurfaceImpl *(const egl::SurfaceState &, SurfaceImpl *(const egl::SurfaceState &,
NativePixmapType, NativePixmapType,
const egl::AttributeMap &)); const egl::AttributeMap &));
MOCK_METHOD3(createImage, ImageImpl *(EGLenum, egl::ImageSibling *, const egl::AttributeMap &)); MOCK_METHOD3(createImage,
ImageImpl *(const egl::ImageState &, EGLenum, const egl::AttributeMap &));
MOCK_METHOD1(createContext, ContextImpl *(const gl::ContextState &)); MOCK_METHOD1(createContext, ContextImpl *(const gl::ContextState &));
MOCK_METHOD2(createStreamProducerD3DTextureNV12, MOCK_METHOD2(createStreamProducerD3DTextureNV12,
StreamProducerImpl *(egl::Stream::ConsumerType, const egl::AttributeMap &)); StreamProducerImpl *(egl::Stream::ConsumerType, const egl::AttributeMap &));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment