Commit dbd16127 by Geoff Lang Committed by Commit Bot

EGL: Implement EGL Image extensions.

BUG=angleproject:2507 Change-Id: Ica33166e9e23e933977c3ab034d4f5a8cada9fb1 Reviewed-on: https://chromium-review.googlesource.com/1143454 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 203b26f2
...@@ -970,6 +970,12 @@ EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType) ...@@ -970,6 +970,12 @@ EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType)
return EGL_NONE; return EGL_NONE;
} }
} }
EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle)
{
return reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(handle));
}
} // namespace gl_egl } // namespace gl_egl
#if !defined(ANGLE_ENABLE_WINDOWS_STORE) #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
......
...@@ -161,6 +161,7 @@ GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer); ...@@ -161,6 +161,7 @@ GLuint EGLClientBufferToGLObjectHandle(EGLClientBuffer buffer);
namespace gl_egl namespace gl_egl
{ {
EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType); EGLenum GLComponentTypeToEGLColorComponentType(GLenum glComponentType);
EGLClientBuffer GLObjectHandleToEGLClientBuffer(GLuint handle);
} // namespace gl_egl } // namespace gl_egl
#if !defined(ANGLE_ENABLE_WINDOWS_STORE) #if !defined(ANGLE_ENABLE_WINDOWS_STORE)
......
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImageGL.cpp: Implements rx::ImageGL class
#include "libANGLE/renderer/gl/ImageGL.h"
namespace rx
{
ImageGL::ImageGL(const egl::ImageState &state) : ImageImpl(state)
{
}
ImageGL::~ImageGL()
{
}
} // namespace rx
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImageGL.h: Defines the rx::ImageGL class, the GL implementation of EGL images
#ifndef LIBANGLE_RENDERER_GL_IMAGEGL_H_
#define LIBANGLE_RENDERER_GL_IMAGEGL_H_
#include "common/PackedEnums.h"
#include "libANGLE/renderer/ImageImpl.h"
namespace rx
{
class TextureGL;
class RenderbufferGL;
class ImageGL : public ImageImpl
{
public:
ImageGL(const egl::ImageState &state);
~ImageGL() override;
// TextureGL does not have access to all the parameters needed to implement
// glEGLImageTargetTexture2DOES or glEGLImageTargetRenderbufferStorageOES. This allows the Image
// to implement these functions because it holds the native EGLimage or emulated object.
virtual gl::Error setTexture2D(const gl::Context *context,
gl::TextureType type,
TextureGL *texture,
GLenum *outInternalFormat) = 0;
virtual gl::Error setRenderbufferStorage(const gl::Context *context,
RenderbufferGL *renderbuffer,
GLenum *outInternalFormat) = 0;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_IMAGEGL_H_
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/renderer/gl/BlitGL.h" #include "libANGLE/renderer/gl/BlitGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/ImageGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/formatutilsgl.h" #include "libANGLE/renderer/gl/formatutilsgl.h"
#include "libANGLE/renderer/gl/renderergl_utils.h" #include "libANGLE/renderer/gl/renderergl_utils.h"
...@@ -99,10 +100,8 @@ gl::Error RenderbufferGL::setStorageMultisample(const gl::Context *context, ...@@ -99,10 +100,8 @@ gl::Error RenderbufferGL::setStorageMultisample(const gl::Context *context,
gl::Error RenderbufferGL::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image) gl::Error RenderbufferGL::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image)
{ {
// TODO(geofflang): If implemented, be sure to update mNativeInternalFormat. ImageGL *imageGL = GetImplAs<ImageGL>(image);
// http://anglebug.com/2412 return imageGL->setRenderbufferStorage(context, this, &mNativeInternalFormat);
UNREACHABLE();
return gl::InternalError();
} }
GLuint RenderbufferGL::getRenderbufferID() const GLuint RenderbufferGL::getRenderbufferID() const
...@@ -116,4 +115,9 @@ gl::Error RenderbufferGL::initializeContents(const gl::Context *context, ...@@ -116,4 +115,9 @@ gl::Error RenderbufferGL::initializeContents(const gl::Context *context,
return mBlitter->clearRenderbuffer(this, mNativeInternalFormat); return mBlitter->clearRenderbuffer(this, mNativeInternalFormat);
} }
GLenum RenderbufferGL::getNativeInternalFormat() const
{
return mNativeInternalFormat;
}
} // namespace rx } // namespace rx
...@@ -50,6 +50,7 @@ class RenderbufferGL : public RenderbufferImpl ...@@ -50,6 +50,7 @@ class RenderbufferGL : public RenderbufferImpl
const gl::ImageIndex &imageIndex) override; const gl::ImageIndex &imageIndex) override;
GLuint getRenderbufferID() const; GLuint getRenderbufferID() const;
GLenum getNativeInternalFormat() const;
private: private:
const FunctionsGL *mFunctions; const FunctionsGL *mFunctions;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "libANGLE/renderer/gl/BufferGL.h" #include "libANGLE/renderer/gl/BufferGL.h"
#include "libANGLE/renderer/gl/FramebufferGL.h" #include "libANGLE/renderer/gl/FramebufferGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/ImageGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/WorkaroundsGL.h" #include "libANGLE/renderer/gl/WorkaroundsGL.h"
#include "libANGLE/renderer/gl/formatutilsgl.h" #include "libANGLE/renderer/gl/formatutilsgl.h"
...@@ -1104,8 +1105,15 @@ gl::Error TextureGL::setEGLImageTarget(const gl::Context *context, ...@@ -1104,8 +1105,15 @@ gl::Error TextureGL::setEGLImageTarget(const gl::Context *context,
gl::TextureType type, gl::TextureType type,
egl::Image *image) egl::Image *image)
{ {
UNIMPLEMENTED(); ImageGL *imageGL = GetImplAs<ImageGL>(image);
return gl::InternalError();
GLenum imageNativeInternalFormat = GL_NONE;
ANGLE_TRY(imageGL->setTexture2D(context, type, this, &imageNativeInternalFormat));
setLevelInfo(type, 0, 1,
GetLevelInfo(image->getFormat().info->internalFormat, imageNativeInternalFormat));
return gl::NoError();
} }
gl::Error TextureGL::syncState(const gl::Context *context, const gl::Texture::DirtyBits &dirtyBits) gl::Error TextureGL::syncState(const gl::Context *context, const gl::Texture::DirtyBits &dirtyBits)
...@@ -1310,6 +1318,11 @@ void TextureGL::setSwizzle(const gl::Context *context, GLint swizzle[4]) ...@@ -1310,6 +1318,11 @@ void TextureGL::setSwizzle(const gl::Context *context, GLint swizzle[4])
} }
} }
GLenum TextureGL::getNativeInternalFormat(const gl::ImageIndex &index) const
{
return getLevelInfo(index.getTarget(), index.getLevelIndex()).nativeInternalFormat;
}
void TextureGL::syncTextureStateSwizzle(const FunctionsGL *functions, void TextureGL::syncTextureStateSwizzle(const FunctionsGL *functions,
GLenum name, GLenum name,
GLenum value, GLenum value,
......
...@@ -177,6 +177,8 @@ class TextureGL : public TextureImpl ...@@ -177,6 +177,8 @@ class TextureGL : public TextureImpl
void setSwizzle(const gl::Context *context, GLint swizzle[4]); void setSwizzle(const gl::Context *context, GLint swizzle[4]);
GLenum getNativeInternalFormat(const gl::ImageIndex &index) const;
private: private:
void setImageHelper(const gl::Context *context, void setImageHelper(const gl::Context *context,
gl::TextureTarget target, gl::TextureTarget target,
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "libANGLE/renderer/gl/egl/DisplayEGL.h" #include "libANGLE/renderer/gl/egl/DisplayEGL.h"
#include "libANGLE/renderer/gl/egl/ImageEGL.h"
#include "libANGLE/renderer/gl/egl/egl_utils.h" #include "libANGLE/renderer/gl/egl/egl_utils.h"
namespace rx namespace rx
...@@ -24,6 +25,14 @@ DisplayEGL::~DisplayEGL() ...@@ -24,6 +25,14 @@ DisplayEGL::~DisplayEGL()
{ {
} }
ImageImpl *DisplayEGL::createImage(const egl::ImageState &state,
const gl::Context *context,
EGLenum target,
const egl::AttributeMap &attribs)
{
return new ImageEGL(state, context, target, attribs, mEGL);
}
std::string DisplayEGL::getVendorString() const std::string DisplayEGL::getVendorString() const
{ {
const char *vendor = mEGL->queryString(EGL_VENDOR); const char *vendor = mEGL->queryString(EGL_VENDOR);
...@@ -113,6 +122,15 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -113,6 +122,15 @@ void DisplayEGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
// supported, so indicate support here to keep validation happy. // supported, so indicate support here to keep validation happy.
outExtensions->swapBuffersWithDamage = true; outExtensions->swapBuffersWithDamage = true;
outExtensions->image = mEGL->hasExtension("EGL_KHR_image");
outExtensions->imageBase = mEGL->hasExtension("EGL_KHR_image_base");
// Pixmaps are not supported in ANGLE's EGL implementation.
// outExtensions->imagePixmap = mEGL->hasExtension("EGL_KHR_image_pixmap");
outExtensions->glTexture2DImage = mEGL->hasExtension("EGL_KHR_gl_texture_2D_image");
outExtensions->glTextureCubemapImage = mEGL->hasExtension("EGL_KHR_gl_texture_cubemap_image");
outExtensions->glTexture3DImage = mEGL->hasExtension("EGL_KHR_gl_texture_3D_image");
outExtensions->glRenderbufferImage = mEGL->hasExtension("EGL_KHR_gl_renderbuffer_image");
DisplayGL::generateExtensions(outExtensions); DisplayGL::generateExtensions(outExtensions);
} }
......
...@@ -21,6 +21,11 @@ class DisplayEGL : public DisplayGL ...@@ -21,6 +21,11 @@ class DisplayEGL : public DisplayGL
DisplayEGL(const egl::DisplayState &state); DisplayEGL(const egl::DisplayState &state);
~DisplayEGL() override; ~DisplayEGL() override;
ImageImpl *createImage(const egl::ImageState &state,
const gl::Context *context,
EGLenum target,
const egl::AttributeMap &attribs) override;
std::string getVendorString() const override; std::string getVendorString() const override;
virtual void destroyNativeContext(EGLContext context) = 0; virtual void destroyNativeContext(EGLContext context) = 0;
......
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImageEGL.cpp: Implements the rx::ImageEGL class.
#include "libANGLE/renderer/gl/egl/ImageEGL.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
#include "libANGLE/renderer/gl/RenderbufferGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/TextureGL.h"
#include "libANGLE/renderer/gl/egl/ContextEGL.h"
#include "libANGLE/renderer/gl/egl/FunctionsEGL.h"
namespace rx
{
ImageEGL::ImageEGL(const egl::ImageState &state,
const gl::Context *context,
EGLenum target,
const egl::AttributeMap &attribs,
const FunctionsEGL *egl)
: ImageGL(state),
mEGL(egl),
mContext(EGL_NO_CONTEXT),
mTarget(target),
mPreserveImage(false),
mImage(EGL_NO_IMAGE)
{
if (context)
{
mContext = GetImplAs<ContextEGL>(context)->getContext();
}
mPreserveImage = attribs.get(EGL_IMAGE_PRESERVED, EGL_FALSE) == EGL_TRUE;
}
ImageEGL::~ImageEGL()
{
mEGL->destroyImageKHR(mImage);
}
egl::Error ImageEGL::initialize(const egl::Display *display)
{
EGLClientBuffer buffer = nullptr;
std::vector<EGLint> attributes;
if (egl::IsTextureTarget(mTarget))
{
attributes.push_back(EGL_GL_TEXTURE_LEVEL);
attributes.push_back(mState.imageIndex.getLevelIndex());
if (mState.imageIndex.has3DLayer())
{
attributes.push_back(EGL_GL_TEXTURE_ZOFFSET);
attributes.push_back(mState.imageIndex.getLayerIndex());
}
const TextureGL *textureGL = GetImplAs<TextureGL>(GetAs<gl::Texture>(mState.source.get()));
buffer = gl_egl::GLObjectHandleToEGLClientBuffer(textureGL->getTextureID());
mNativeInternalFormat = textureGL->getNativeInternalFormat(mState.imageIndex);
}
else if (egl::IsRenderbufferTarget(mTarget))
{
const RenderbufferGL *renderbufferGL =
GetImplAs<RenderbufferGL>(GetAs<gl::Renderbuffer>(mState.source.get()));
buffer = gl_egl::GLObjectHandleToEGLClientBuffer(renderbufferGL->getRenderbufferID());
mNativeInternalFormat = renderbufferGL->getNativeInternalFormat();
}
else
{
UNREACHABLE();
}
attributes.push_back(EGL_IMAGE_PRESERVED);
attributes.push_back(mPreserveImage ? EGL_TRUE : EGL_FALSE);
attributes.push_back(EGL_NONE);
mImage = mEGL->createImageKHR(mContext, mTarget, buffer, attributes.data());
if (mImage == EGL_NO_IMAGE)
{
return egl::EglBadAlloc() << "eglCreateImage failed with " << egl::Error(mEGL->getError());
}
return egl::NoError();
}
gl::Error ImageEGL::orphan(const gl::Context *context, egl::ImageSibling *sibling)
{
// Nothing to do, the native EGLImage will orphan automatically.
return gl::NoError();
}
gl::Error ImageEGL::setTexture2D(const gl::Context *context,
gl::TextureType type,
TextureGL *texture,
GLenum *outInternalFormat)
{
const FunctionsGL *functionsGL = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
// Make sure this texture is bound
stateManager->bindTexture(type, texture->getTextureID());
// Bind the image to the texture
functionsGL->eGLImageTargetTexture2DOES(ToGLenum(type), mImage);
*outInternalFormat = mNativeInternalFormat;
return gl::NoError();
}
gl::Error ImageEGL::setRenderbufferStorage(const gl::Context *context,
RenderbufferGL *renderbuffer,
GLenum *outInternalFormat)
{
const FunctionsGL *functionsGL = GetFunctionsGL(context);
StateManagerGL *stateManager = GetStateManagerGL(context);
// Make sure this renderbuffer is bound
stateManager->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer->getRenderbufferID());
// Bind the image to the renderbuffer
functionsGL->eGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage);
*outInternalFormat = mNativeInternalFormat;
return gl::NoError();
}
} // namespace rx
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ImageEGL.h: Defines the rx::ImageEGL class, the EGL implementation of EGL images
#ifndef LIBANGLE_RENDERER_GL_EGL_IMAGEEGL_H_
#define LIBANGLE_RENDERER_GL_EGL_IMAGEEGL_H_
#include "libANGLE/renderer/gl/ImageGL.h"
namespace egl
{
class AttributeMap;
}
namespace rx
{
class FunctionsEGL;
class ImageEGL final : public ImageGL
{
public:
ImageEGL(const egl::ImageState &state,
const gl::Context *context,
EGLenum target,
const egl::AttributeMap &attribs,
const FunctionsEGL *egl);
~ImageEGL() override;
egl::Error initialize(const egl::Display *display) override;
gl::Error orphan(const gl::Context *context, egl::ImageSibling *sibling) override;
gl::Error setTexture2D(const gl::Context *context,
gl::TextureType type,
TextureGL *texture,
GLenum *outInternalFormat) override;
gl::Error setRenderbufferStorage(const gl::Context *context,
RenderbufferGL *renderbuffer,
GLenum *outInternalFormat) override;
private:
const FunctionsEGL *mEGL;
// State needed for initialization
EGLContext mContext;
EGLenum mTarget;
bool mPreserveImage;
GLenum mNativeInternalFormat;
EGLImage mImage;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_EGL_IMAGEEGL_H_
...@@ -941,6 +941,12 @@ void GenerateCaps(const FunctionsGL *functions, ...@@ -941,6 +941,12 @@ void GenerateCaps(const FunctionsGL *functions,
functions->isAtLeastGLES(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
functions->hasGLESExtension("GL_KHR_debug") || functions->hasGLESExtension("GL_KHR_debug") ||
functions->hasGLESExtension("GL_EXT_debug_marker"); functions->hasGLESExtension("GL_EXT_debug_marker");
extensions->eglImage = functions->hasGLESExtension("GL_OES_EGL_image");
// TODO(geofflang): Support external texture targets in TextureGL. http://anglebug.com/2507
// extensions->eglImageExternal = functions->hasGLESExtension("GL_OES_EGL_image_external");
// extensions->eglImageExternalEssl3 =
// functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
if (functions->isAtLeastGL(gl::Version(3, 3)) || if (functions->isAtLeastGL(gl::Version(3, 3)) ||
functions->hasGLExtension("GL_ARB_timer_query") || functions->hasGLExtension("GL_ARB_timer_query") ||
functions->hasGLESExtension("GL_EXT_disjoint_timer_query")) functions->hasGLESExtension("GL_EXT_disjoint_timer_query"))
......
...@@ -636,6 +636,8 @@ ...@@ -636,6 +636,8 @@
'libANGLE/renderer/gl/FramebufferGL.h', 'libANGLE/renderer/gl/FramebufferGL.h',
'libANGLE/renderer/gl/FunctionsGL.cpp', 'libANGLE/renderer/gl/FunctionsGL.cpp',
'libANGLE/renderer/gl/FunctionsGL.h', 'libANGLE/renderer/gl/FunctionsGL.h',
'libANGLE/renderer/gl/ImageGL.cpp',
'libANGLE/renderer/gl/ImageGL.h',
'libANGLE/renderer/gl/PathGL.h', 'libANGLE/renderer/gl/PathGL.h',
'libANGLE/renderer/gl/PathGL.cpp', 'libANGLE/renderer/gl/PathGL.cpp',
'libANGLE/renderer/gl/ProgramGL.cpp', 'libANGLE/renderer/gl/ProgramGL.cpp',
...@@ -725,6 +727,8 @@ ...@@ -725,6 +727,8 @@
'libANGLE/renderer/gl/egl/egl_utils.h', 'libANGLE/renderer/gl/egl/egl_utils.h',
'libANGLE/renderer/gl/egl/FunctionsEGL.cpp', 'libANGLE/renderer/gl/egl/FunctionsEGL.cpp',
'libANGLE/renderer/gl/egl/FunctionsEGL.h', 'libANGLE/renderer/gl/egl/FunctionsEGL.h',
'libANGLE/renderer/gl/egl/ImageEGL.cpp',
'libANGLE/renderer/gl/egl/ImageEGL.h',
'libANGLE/renderer/gl/egl/functionsegl_typedefs.h', 'libANGLE/renderer/gl/egl/functionsegl_typedefs.h',
'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp', 'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp',
'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h', 'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h',
......
...@@ -236,6 +236,14 @@ ...@@ -236,6 +236,14 @@
2546 MAC : dEQP-EGL.functional.color_clears.multi_thread.* = SKIP 2546 MAC : dEQP-EGL.functional.color_clears.multi_thread.* = SKIP
2546 MAC : dEQP-EGL.functional.thread_cleanup.* = SKIP 2546 MAC : dEQP-EGL.functional.thread_cleanup.* = SKIP
// Android GLES-only failues
2567 ANDROID GLES : dEQP-EGL.functional.image.api.create_image_gles2_tex2d_red = FAIL
2567 ANDROID GLES : dEQP-EGL.functional.image.api.create_image_gles2_tex2d_rg = FAIL
2507 ANDROID GLES : dEQP-EGL.functional.image.modify.renderbuffer_rgb565_tex_subimage_rgb8 = FAIL
2507 ANDROID GLES : dEQP-EGL.functional.image.modify.renderbuffer_rgba4_tex_subimage_rgba8 = FAIL
2507 ANDROID GLES : dEQP-EGL.functional.image.modify.tex_rgb565_tex_subimage_rgb8 = FAIL
2507 ANDROID GLES : dEQP-EGL.functional.image.modify.tex_rgba4_tex_subimage_rgba8 = FAIL
// Android failures // Android failures
2546 ANDROID : dEQP-EGL.functional.multithread.* = SKIP 2546 ANDROID : dEQP-EGL.functional.multithread.* = SKIP
2546 ANDROID : dEQP-EGL.functional.render.multi_thread.* = SKIP 2546 ANDROID : dEQP-EGL.functional.render.multi_thread.* = SKIP
......
...@@ -458,6 +458,9 @@ class ImageTestES3 : public ImageTest ...@@ -458,6 +458,9 @@ class ImageTestES3 : public ImageTest
// you change extension availability. // you change extension availability.
TEST_P(ImageTest, ANGLEExtensionAvailability) TEST_P(ImageTest, ANGLEExtensionAvailability)
{ {
// Android support is based on driver extension availability.
ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsAndroid());
if (IsD3D11() || IsD3D9()) if (IsD3D11() || IsD3D9())
{ {
EXPECT_TRUE(hasOESExt()); EXPECT_TRUE(hasOESExt());
...@@ -1292,6 +1295,10 @@ TEST_P(ImageTest, Source3DTargetTexture) ...@@ -1292,6 +1295,10 @@ TEST_P(ImageTest, Source3DTargetTexture)
TEST_P(ImageTest, Source3DTargetRenderbuffer) TEST_P(ImageTest, Source3DTargetRenderbuffer)
{ {
// Qualcom drivers appear to always bind the 0 layer of the source 3D texture when the target is
// a renderbuffer. They work correctly when the target is a 2D texture. http://anglebug.com/2745
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has3DTextureExt()); ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has3DTextureExt());
...@@ -1621,6 +1628,10 @@ TEST_P(ImageTest, MipLevels) ...@@ -1621,6 +1628,10 @@ TEST_P(ImageTest, MipLevels)
// Respecify the source texture, orphaning it. The target texture should not have updated data. // Respecify the source texture, orphaning it. The target texture should not have updated data.
TEST_P(ImageTest, Respecification) TEST_P(ImageTest, Respecification)
{ {
// Respecification of textures that does not change the size of the level attached to the EGL
// image does not cause orphaning on Qualcomm devices. http://anglebug.com/2744
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt()); ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
...@@ -1652,6 +1663,41 @@ TEST_P(ImageTest, Respecification) ...@@ -1652,6 +1663,41 @@ TEST_P(ImageTest, Respecification)
glDeleteTextures(1, &target); glDeleteTextures(1, &target);
} }
// Respecify the source texture with a different size, orphaning it. The target texture should not
// have updated data.
TEST_P(ImageTest, RespecificationDifferentSize)
{
EGLWindow *window = getEGLWindow();
ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
GLubyte originalData[4] = {255, 0, 255, 255};
GLubyte updateData[16] = {0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
// Create the Image
GLuint source;
EGLImageKHR image;
createEGLImage2DTextureSource(1, 1, GL_RGBA, GL_UNSIGNED_BYTE, originalData, &source, &image);
// Create the target
GLuint target;
createEGLImageTargetTexture2D(image, &target);
// Respecify source
glBindTexture(GL_TEXTURE_2D, source);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, updateData);
// Expect that the target texture has the original data
verifyResults2D(target, originalData);
// Expect that the source texture has the updated data
verifyResults2D(source, updateData);
// Clean up
glDeleteTextures(1, &source);
eglDestroyImageKHR(window->getDisplay(), image);
glDeleteTextures(1, &target);
}
// First render to a target texture, then respecify the source texture, orphaning it. // First render to a target texture, then respecify the source texture, orphaning it.
// The target texture's FBO should be notified of the target texture's orphaning. // The target texture's FBO should be notified of the target texture's orphaning.
TEST_P(ImageTest, RespecificationWithFBO) TEST_P(ImageTest, RespecificationWithFBO)
...@@ -1705,6 +1751,10 @@ TEST_P(ImageTest, RespecificationWithFBO) ...@@ -1705,6 +1751,10 @@ TEST_P(ImageTest, RespecificationWithFBO)
// data // data
TEST_P(ImageTest, RespecificationOfOtherLevel) TEST_P(ImageTest, RespecificationOfOtherLevel)
{ {
// Respecification of textures that does not change the size of the level attached to the EGL
// image does not cause orphaning on Qualcomm devices. http://anglebug.com/2744
ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt()); ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt() || !has2DTextureExt());
......
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