зеркало из https://github.com/AvaloniaUI/angle.git
EGL: GLES: Implement GL_EXT_protected_textures
Implement EGL_EXT_protected_content Images Add protected member to Images and Textures Add error when creating objects if not supported or does't match native buffer When creating siblings pass protected state Add extension caps Add Validation Add GetTexParameter and SetTextparameter Add protected to Texture and state Expand tests for images and textures Test: angle_end2end_test --gtest_filter=EGLProtectedContentTest Bug: angleproject:3965 Change-Id: I35a89b4e80bba6d9b6831c68e71630eef304dacb Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2802852 Commit-Queue: Mohan Maiya <m.maiya@samsung.com> Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
This commit is contained in:
Родитель
d2b659f9a1
Коммит
6210a9b34a
|
@ -12,7 +12,7 @@
|
|||
"scripts/gl_angle_ext.xml":
|
||||
"08f74b35d908b7c02b45fdf45572c434",
|
||||
"scripts/registry_xml.py":
|
||||
"3fc0ede1891f7de9338993dea77df9e8",
|
||||
"44a6f8c6713b39de5427da86b6c64595",
|
||||
"scripts/wgl.xml":
|
||||
"c36001431919e1c435f1215a85f7e1db",
|
||||
"src/libEGL/egl_loader_autogen.cpp":
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"scripts/gl_angle_ext.xml":
|
||||
"08f74b35d908b7c02b45fdf45572c434",
|
||||
"scripts/registry_xml.py":
|
||||
"3fc0ede1891f7de9338993dea77df9e8",
|
||||
"44a6f8c6713b39de5427da86b6c64595",
|
||||
"scripts/wgl.xml":
|
||||
"c36001431919e1c435f1215a85f7e1db",
|
||||
"src/common/entry_points_enum_autogen.cpp":
|
||||
|
@ -42,7 +42,7 @@
|
|||
"src/libANGLE/Context_gles_3_2_autogen.h":
|
||||
"48567dca16fd881dfe6d61fee0e3106f",
|
||||
"src/libANGLE/Context_gles_ext_autogen.h":
|
||||
"dbf7c9716e46e29b44db01f215f0808a",
|
||||
"1e78e832b23a36d8b0eb290ebfd95812",
|
||||
"src/libANGLE/capture/capture_gles_1_0_autogen.cpp":
|
||||
"7ec7ef8f779b809a45d74b97502c419b",
|
||||
"src/libANGLE/capture/capture_gles_1_0_autogen.h":
|
||||
|
@ -66,7 +66,7 @@
|
|||
"src/libANGLE/capture/capture_gles_ext_autogen.cpp":
|
||||
"b027d574c21f369aee0fb0117f453935",
|
||||
"src/libANGLE/capture/capture_gles_ext_autogen.h":
|
||||
"46440404fc9219fbe709e564f26d57a6",
|
||||
"42d26ead58cf52c8bbf2701589bc68aa",
|
||||
"src/libANGLE/capture/frame_capture_replay_autogen.cpp":
|
||||
"e0a3c284b986e2a712589b6f3523d79c",
|
||||
"src/libANGLE/capture/frame_capture_utils_autogen.cpp":
|
||||
|
@ -88,7 +88,7 @@
|
|||
"src/libANGLE/validationES3_autogen.h":
|
||||
"7435b9caddf8787b937c71a54dda96e1",
|
||||
"src/libANGLE/validationESEXT_autogen.h":
|
||||
"498a3fcf388dd8edbe38b25aaa1621cc",
|
||||
"b2d36e26a63cd92fbb26d289f1aecb9b",
|
||||
"src/libANGLE/validationGL1_autogen.h":
|
||||
"439f8ea26dc37ee6608100f4c6f9205c",
|
||||
"src/libANGLE/validationGL2_autogen.h":
|
||||
|
@ -162,17 +162,17 @@
|
|||
"src/libGLESv2/entry_points_gles_3_2_autogen.h":
|
||||
"647f932a299cdb4726b60bbba059f0d2",
|
||||
"src/libGLESv2/entry_points_gles_ext_autogen.cpp":
|
||||
"dda68d8198adeb87c19f5fce8691a0b9",
|
||||
"df737a111291710513eda6f38d391b26",
|
||||
"src/libGLESv2/entry_points_gles_ext_autogen.h":
|
||||
"95374bec6b53708d019455309ea887ec",
|
||||
"5be077957c8cf2dbf10be897d56ef4ed",
|
||||
"src/libGLESv2/libGLESv2_autogen.cpp":
|
||||
"3805edff53f627f34ce6f55f064e473c",
|
||||
"e6fd37cfcb725f9d3a25cc9c55a1ea40",
|
||||
"src/libGLESv2/libGLESv2_autogen.def":
|
||||
"b49ee14e4c440282d86e5ab4acbaaff5",
|
||||
"7f8231e286656964204c1f303e91dfc9",
|
||||
"src/libGLESv2/libGLESv2_no_capture_autogen.def":
|
||||
"2303964798f342d2858dc44ba9f02a2e",
|
||||
"e243621778233766d10df30029d4e2c7",
|
||||
"src/libGLESv2/libGLESv2_with_capture_autogen.def":
|
||||
"b74c9e193df59dc0f06ff45308f8fb51",
|
||||
"cce23e17f23ef38ee99869b6bc3d8729",
|
||||
"src/libOpenCL/libOpenCL_autogen.cpp":
|
||||
"10849978c910dc1af5dd4f0c815d1581"
|
||||
}
|
|
@ -6,9 +6,9 @@
|
|||
"scripts/gl_angle_ext.xml":
|
||||
"08f74b35d908b7c02b45fdf45572c434",
|
||||
"scripts/registry_xml.py":
|
||||
"3fc0ede1891f7de9338993dea77df9e8",
|
||||
"44a6f8c6713b39de5427da86b6c64595",
|
||||
"src/libANGLE/capture/gl_enum_utils_autogen.cpp":
|
||||
"335140f98374899f9e1303b23b4eddc1",
|
||||
"9f432722dc11c315b6920d311d8df70e",
|
||||
"src/libANGLE/capture/gl_enum_utils_autogen.h":
|
||||
"fb0bb7f506f6082ea3b2c3fa384d2739"
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
"scripts/gl_angle_ext.xml":
|
||||
"08f74b35d908b7c02b45fdf45572c434",
|
||||
"scripts/registry_xml.py":
|
||||
"3fc0ede1891f7de9338993dea77df9e8",
|
||||
"44a6f8c6713b39de5427da86b6c64595",
|
||||
"scripts/wgl.xml":
|
||||
"c36001431919e1c435f1215a85f7e1db",
|
||||
"src/libGL/proc_table_wgl_autogen.cpp":
|
||||
|
|
|
@ -90,6 +90,7 @@ gles_extensions = [
|
|||
"GL_EXT_multisampled_render_to_texture2",
|
||||
"GL_EXT_occlusion_query_boolean",
|
||||
"GL_EXT_primitive_bounding_box",
|
||||
"GL_EXT_protected_textures",
|
||||
"GL_EXT_read_format_bgra",
|
||||
"GL_EXT_robustness",
|
||||
"GL_EXT_semaphore",
|
||||
|
|
|
@ -334,13 +334,15 @@ void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
|
|||
int *width,
|
||||
int *height,
|
||||
int *depth,
|
||||
int *pixelFormat)
|
||||
int *pixelFormat,
|
||||
uint64_t *usage)
|
||||
{
|
||||
*width = buffer->width;
|
||||
*height = buffer->height;
|
||||
*depth = static_cast<int>(buffer->layerCount);
|
||||
*height = buffer->height;
|
||||
*pixelFormat = buffer->format;
|
||||
*usage = buffer->usage;
|
||||
}
|
||||
|
||||
GLenum NativePixelFormatToGLInternalFormat(int pixelFormat)
|
||||
|
|
|
@ -42,7 +42,8 @@ void GetANativeWindowBufferProperties(const ANativeWindowBuffer *buffer,
|
|||
int *width,
|
||||
int *height,
|
||||
int *depth,
|
||||
int *pixelFormat);
|
||||
int *pixelFormat,
|
||||
uint64_t *usage);
|
||||
GLenum NativePixelFormatToGLInternalFormat(int pixelFormat);
|
||||
int GLInternalFormatToNativePixelFormat(GLenum internalFormat);
|
||||
|
||||
|
|
|
@ -1097,6 +1097,7 @@ const ExtensionInfoMap &GetExtensionInfoMap()
|
|||
map["GL_EXT_primitive_bounding_box"] = esOnlyExtension(&Extensions::primitiveBoundingBoxEXT);
|
||||
map["GL_ANGLE_relaxed_vertex_attribute_type"] = esOnlyExtension(&Extensions::relaxedVertexAttributeTypeANGLE);
|
||||
map["GL_ANGLE_yuv_internal_format"] = enableableExtension(&Extensions::yuvInternalFormatANGLE);
|
||||
map["GL_EXT_protected_textures"] = enableableExtension(&Extensions::protectedTexturesEXT);
|
||||
// GLES1 extensions
|
||||
map["GL_OES_point_size_array"] = enableableExtension(&Extensions::pointSizeArrayOES);
|
||||
map["GL_OES_texture_cube_map"] = enableableExtension(&Extensions::textureCubeMapOES);
|
||||
|
|
|
@ -741,6 +741,9 @@ struct Extensions
|
|||
|
||||
// GL_ANGLE_yuv_internal_format
|
||||
bool yuvInternalFormatANGLE = false;
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
bool protectedTexturesEXT = false;
|
||||
};
|
||||
|
||||
// Pointer to a boolean memeber of the Extensions struct
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
// Context.cpp: Implements the gl::Context class, managing all GL state and performing
|
||||
// rendering operations. It is the GLES2 specific implementation of EGLContext.
|
||||
|
||||
#include "libANGLE/Context.h"
|
||||
#include "libANGLE/Context.inl.h"
|
||||
|
||||
|
@ -3559,6 +3558,14 @@ Extensions Context::generateSupportedExtensions() const
|
|||
ASSERT(supportedExtensions.textureCompressionASTCHDRKHR);
|
||||
}
|
||||
|
||||
// GL_KHR_protected_textures
|
||||
// If EGL_KHR_protected_content is not supported then GL_EXT_protected_texture
|
||||
// can not be supported.
|
||||
if (!mDisplay->getExtensions().protectedContentEXT)
|
||||
{
|
||||
supportedExtensions.protectedTexturesEXT = false;
|
||||
}
|
||||
|
||||
// GL_ANGLE_get_tex_level_parameter is implemented in the frontend
|
||||
supportedExtensions.getTexLevelParameterANGLE = true;
|
||||
|
||||
|
|
|
@ -184,6 +184,7 @@
|
|||
/* GL_EXT_multisampled_render_to_texture2 */ \
|
||||
/* GL_EXT_occlusion_query_boolean */ \
|
||||
/* GL_EXT_primitive_bounding_box */ \
|
||||
/* GL_EXT_protected_textures */ \
|
||||
/* GL_EXT_read_format_bgra */ \
|
||||
/* GL_EXT_robustness */ \
|
||||
/* GL_EXT_sRGB */ \
|
||||
|
|
|
@ -567,6 +567,7 @@ MSG kProgramNotSeparable = "Program object was not linked with its PROGRAM_SEPAR
|
|||
MSG kProgramPipelineDoesNotExist = "Program pipeline does not exist.";
|
||||
MSG kNotAllStagesOfSeparableProgramUsed = "A program object is active for at least one, but not all of the shader stages that were present when the program was linked.";
|
||||
MSG kProgramPipelineLinkFailed = "Program pipeline link failed";
|
||||
MSG kProtectedTexturesExtensionRequired = "GL_EXT_protected_textures not enabled.";
|
||||
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -212,6 +212,7 @@ class FramebufferAttachmentObject : public angle::Subject, public angle::Observe
|
|||
GLenum binding,
|
||||
const ImageIndex &imageIndex) const = 0;
|
||||
virtual bool isYUV() const = 0;
|
||||
virtual bool hasProtectedContent() const = 0;
|
||||
|
||||
virtual void onAttach(const Context *context, rx::Serial framebufferSerial) = 0;
|
||||
virtual void onDetach(const Context *context, rx::Serial framebufferSerial) = 0;
|
||||
|
|
|
@ -135,6 +135,11 @@ bool ImageSibling::isYUV() const
|
|||
return mTargetOf.get() && mTargetOf->isYUV();
|
||||
}
|
||||
|
||||
bool ImageSibling::hasProtectedContent() const
|
||||
{
|
||||
return mTargetOf.get() && mTargetOf->hasProtectedContent();
|
||||
}
|
||||
|
||||
void ImageSibling::notifySiblings(angle::SubjectMessage message)
|
||||
{
|
||||
if (mTargetOf.get())
|
||||
|
@ -203,6 +208,11 @@ bool ExternalImageSibling::isYUV() const
|
|||
return mImplementation->isYUV();
|
||||
}
|
||||
|
||||
bool ExternalImageSibling::hasProtectedContent() const
|
||||
{
|
||||
return mImplementation->hasProtectedContent();
|
||||
}
|
||||
|
||||
void ExternalImageSibling::onAttach(const gl::Context *context, rx::Serial framebufferSerial) {}
|
||||
|
||||
void ExternalImageSibling::onDetach(const gl::Context *context, rx::Serial framebufferSerial) {}
|
||||
|
@ -249,7 +259,8 @@ ImageState::ImageState(EGLenum target, ImageSibling *buffer, const AttributeMap
|
|||
samples(),
|
||||
sourceType(target),
|
||||
colorspace(
|
||||
static_cast<EGLenum>(attribs.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_DEFAULT_EXT)))
|
||||
static_cast<EGLenum>(attribs.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_DEFAULT_EXT))),
|
||||
hasProtectedContent(static_cast<bool>(attribs.get(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE)))
|
||||
{}
|
||||
|
||||
ImageState::~ImageState() {}
|
||||
|
@ -414,6 +425,11 @@ size_t Image::getSamples() const
|
|||
return mState.samples;
|
||||
}
|
||||
|
||||
bool Image::hasProtectedContent() const
|
||||
{
|
||||
return mState.hasProtectedContent;
|
||||
}
|
||||
|
||||
rx::ImageImpl *Image::getImplementation() const
|
||||
{
|
||||
return mImplementation;
|
||||
|
@ -426,6 +442,8 @@ Error Image::initialize(const Display *display)
|
|||
ExternalImageSibling *externalSibling = rx::GetAs<ExternalImageSibling>(mState.source);
|
||||
ANGLE_TRY(externalSibling->initialize(display));
|
||||
|
||||
mState.hasProtectedContent = externalSibling->hasProtectedContent();
|
||||
|
||||
// Only external siblings can be YUV
|
||||
mState.yuv = externalSibling->isYUV();
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ class ImageSibling : public gl::FramebufferAttachmentObject
|
|||
GLenum binding,
|
||||
const gl::ImageIndex &imageIndex) const override;
|
||||
bool isYUV() const override;
|
||||
bool hasProtectedContent() const override;
|
||||
|
||||
protected:
|
||||
// Set the image target of this sibling
|
||||
|
@ -99,6 +100,7 @@ class ExternalImageSibling : public ImageSibling
|
|||
const gl::ImageIndex &imageIndex) const override;
|
||||
bool isTextureable(const gl::Context *context) const;
|
||||
bool isYUV() const override;
|
||||
bool hasProtectedContent() const override;
|
||||
|
||||
void onAttach(const gl::Context *context, rx::Serial framebufferSerial) override;
|
||||
void onDetach(const gl::Context *context, rx::Serial framebufferSerial) override;
|
||||
|
@ -137,6 +139,7 @@ struct ImageState : private angle::NonCopyable
|
|||
size_t samples;
|
||||
EGLenum sourceType;
|
||||
EGLenum colorspace;
|
||||
bool hasProtectedContent;
|
||||
};
|
||||
|
||||
class Image final : public RefCountObject, public LabeledObject
|
||||
|
@ -162,6 +165,7 @@ class Image final : public RefCountObject, public LabeledObject
|
|||
size_t getHeight() const;
|
||||
bool isLayered() const;
|
||||
size_t getSamples() const;
|
||||
bool hasProtectedContent() const;
|
||||
|
||||
Error initialize(const Display *display);
|
||||
|
||||
|
|
|
@ -18,7 +18,8 @@ MemoryObject::MemoryObject(rx::GLImplFactory *factory, MemoryObjectID id)
|
|||
: RefCountObject(factory->generateSerial(), id),
|
||||
mImplementation(factory->createMemoryObject()),
|
||||
mImmutable(false),
|
||||
mDedicatedMemory(false)
|
||||
mDedicatedMemory(false),
|
||||
mProtectedMemory(false)
|
||||
{}
|
||||
|
||||
MemoryObject::~MemoryObject() {}
|
||||
|
@ -35,6 +36,13 @@ angle::Result MemoryObject::setDedicatedMemory(const Context *context, bool dedi
|
|||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result MemoryObject::setProtectedMemory(const Context *context, bool protectedMemory)
|
||||
{
|
||||
ANGLE_TRY(mImplementation->setProtectedMemory(context, protectedMemory));
|
||||
mProtectedMemory = protectedMemory;
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result MemoryObject::importFd(Context *context,
|
||||
GLuint64 size,
|
||||
HandleType handleType,
|
||||
|
|
|
@ -38,6 +38,8 @@ class MemoryObject final : public RefCountObject<MemoryObjectID>
|
|||
|
||||
angle::Result setDedicatedMemory(const Context *context, bool dedicatedMemory);
|
||||
bool isDedicatedMemory() const { return mDedicatedMemory; }
|
||||
angle::Result setProtectedMemory(const Context *context, bool protectedMemory);
|
||||
bool isProtectedMemory() const { return mProtectedMemory; }
|
||||
|
||||
angle::Result importFd(Context *context, GLuint64 size, HandleType handleType, GLint fd);
|
||||
angle::Result importZirconHandle(Context *context,
|
||||
|
@ -50,6 +52,7 @@ class MemoryObject final : public RefCountObject<MemoryObjectID>
|
|||
|
||||
bool mImmutable;
|
||||
bool mDedicatedMemory;
|
||||
bool mProtectedMemory;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
|
|
|
@ -34,6 +34,7 @@ RenderbufferState::RenderbufferState()
|
|||
mFormat(GL_RGBA4),
|
||||
mSamples(0),
|
||||
mMultisamplingMode(MultisamplingMode::Regular),
|
||||
mHasProtectedContent(false),
|
||||
mInitState(InitState::Initialized)
|
||||
{}
|
||||
|
||||
|
@ -76,12 +77,18 @@ void RenderbufferState::update(GLsizei width,
|
|||
MultisamplingMode multisamplingMode,
|
||||
InitState initState)
|
||||
{
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFormat = format;
|
||||
mSamples = samples;
|
||||
mMultisamplingMode = multisamplingMode;
|
||||
mInitState = InitState::MayNeedInit;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mFormat = format;
|
||||
mSamples = samples;
|
||||
mMultisamplingMode = multisamplingMode;
|
||||
mInitState = InitState::MayNeedInit;
|
||||
mHasProtectedContent = false;
|
||||
}
|
||||
|
||||
void RenderbufferState::setProtectedContent(bool hasProtectedContent)
|
||||
{
|
||||
mHasProtectedContent = hasProtectedContent;
|
||||
}
|
||||
|
||||
// Renderbuffer implementation.
|
||||
|
@ -164,6 +171,8 @@ angle::Result Renderbuffer::setStorageEGLImageTarget(const Context *context, egl
|
|||
mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()),
|
||||
Format(image->getFormat()), 0, MultisamplingMode::Regular,
|
||||
image->sourceInitState());
|
||||
mState.setProtectedContent(image->hasProtectedContent());
|
||||
|
||||
onStateChange(angle::SubjectMessage::SubjectChanged);
|
||||
|
||||
return angle::Result::Continue;
|
||||
|
|
|
@ -44,6 +44,7 @@ class RenderbufferState final : angle::NonCopyable
|
|||
GLsizei getSamples() const;
|
||||
MultisamplingMode getMultisamplingMode() const;
|
||||
InitState getInitState() const;
|
||||
void setProtectedContent(bool hasProtectedContent);
|
||||
|
||||
private:
|
||||
friend class Renderbuffer;
|
||||
|
@ -60,6 +61,7 @@ class RenderbufferState final : angle::NonCopyable
|
|||
Format mFormat;
|
||||
GLsizei mSamples;
|
||||
MultisamplingMode mMultisamplingMode;
|
||||
bool mHasProtectedContent;
|
||||
|
||||
// For robust resource init.
|
||||
InitState mInitState;
|
||||
|
|
|
@ -133,7 +133,7 @@ class Surface : public LabeledObject, public gl::FramebufferAttachmentObject
|
|||
EGLint getHorizontalResolution() const;
|
||||
EGLint getVerticalResolution() const;
|
||||
EGLenum getMultisampleResolve() const;
|
||||
bool hasProtectedContent() const;
|
||||
bool hasProtectedContent() const override;
|
||||
|
||||
gl::Texture *getBoundTexture() const { return mTexture; }
|
||||
|
||||
|
|
|
@ -144,6 +144,7 @@ TextureState::TextureState(TextureType type)
|
|||
mImmutableFormat(false),
|
||||
mImmutableLevels(0),
|
||||
mUsage(GL_NONE),
|
||||
mHasProtectedContent(false),
|
||||
mImageDescs((IMPLEMENTATION_MAX_TEXTURE_LEVELS + 1) * (type == TextureType::CubeMap ? 6 : 1)),
|
||||
mCropRect(0, 0, 0, 0),
|
||||
mGenerateMipmapHint(GL_FALSE),
|
||||
|
@ -1065,6 +1066,16 @@ GLenum Texture::getUsage() const
|
|||
return mState.mUsage;
|
||||
}
|
||||
|
||||
void Texture::setProtectedContent(Context *context, bool hasProtectedContent)
|
||||
{
|
||||
mState.mHasProtectedContent = hasProtectedContent;
|
||||
}
|
||||
|
||||
bool Texture::hasProtectedContent() const
|
||||
{
|
||||
return mState.mHasProtectedContent;
|
||||
}
|
||||
|
||||
const TextureState &Texture::getTextureState() const
|
||||
{
|
||||
return mState;
|
||||
|
@ -1735,6 +1746,7 @@ angle::Result Texture::bindTexImageFromSurface(Context *context, egl::Surface *s
|
|||
Extents size(surface->getWidth(), surface->getHeight(), 1);
|
||||
ImageDesc desc(size, surface->getBindTexImageFormat(), InitState::Initialized);
|
||||
mState.setImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0, desc);
|
||||
mState.mHasProtectedContent = surface->hasProtectedContent();
|
||||
signalDirtyStorage(InitState::Initialized);
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
@ -1748,6 +1760,7 @@ angle::Result Texture::releaseTexImageFromSurface(const Context *context)
|
|||
// Erase the image info for level 0
|
||||
ASSERT(mState.mType == TextureType::_2D || mState.mType == TextureType::Rectangle);
|
||||
mState.clearImageDesc(NonCubeTextureTypeToTarget(mState.mType), 0);
|
||||
mState.mHasProtectedContent = false;
|
||||
signalDirtyStorage(InitState::Initialized);
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
@ -1838,6 +1851,7 @@ angle::Result Texture::setEGLImageTarget(Context *context,
|
|||
mState.clearImageDescs();
|
||||
mState.setImageDesc(NonCubeTextureTypeToTarget(type), 0,
|
||||
ImageDesc(size, imageTarget->getFormat(), initState));
|
||||
mState.mHasProtectedContent = imageTarget->hasProtectedContent();
|
||||
signalDirtyStorage(initState);
|
||||
|
||||
return angle::Result::Continue;
|
||||
|
|
|
@ -143,6 +143,7 @@ class TextureState final : private angle::NonCopyable
|
|||
const SwizzleState &getSwizzleState() const { return mSwizzleState; }
|
||||
const SamplerState &getSamplerState() const { return mSamplerState; }
|
||||
GLenum getUsage() const { return mUsage; }
|
||||
bool hasProtectedContent() const { return mHasProtectedContent; }
|
||||
GLenum getDepthStencilTextureMode() const { return mDepthStencilTextureMode; }
|
||||
bool isStencilMode() const { return mDepthStencilTextureMode == GL_STENCIL_INDEX; }
|
||||
|
||||
|
@ -224,6 +225,9 @@ class TextureState final : private angle::NonCopyable
|
|||
// From GL_ANGLE_texture_usage
|
||||
GLenum mUsage;
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
bool mHasProtectedContent;
|
||||
|
||||
std::vector<ImageDesc> mImageDescs;
|
||||
|
||||
// GLES1 emulation: Texture crop rectangle
|
||||
|
@ -328,6 +332,9 @@ class Texture final : public RefCountObject<TextureID>,
|
|||
void setUsage(const Context *context, GLenum usage);
|
||||
GLenum getUsage() const;
|
||||
|
||||
void setProtectedContent(Context *context, bool hasProtectedContent);
|
||||
bool hasProtectedContent() const override;
|
||||
|
||||
const TextureState &getState() const { return mState; }
|
||||
|
||||
void setBorderColor(const Context *context, const ColorGeneric &color);
|
||||
|
|
|
@ -1273,6 +1273,8 @@ angle::CallCapture CapturePrimitiveBoundingBoxEXT(const State &glState,
|
|||
GLfloat maxZ,
|
||||
GLfloat maxW);
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
|
||||
// GL_EXT_read_format_bgra
|
||||
|
||||
// GL_EXT_robustness
|
||||
|
|
|
@ -535,6 +535,8 @@ const char *GLenumToString(GLenumGroup enumGroup, unsigned int value)
|
|||
return "GL_CONTEXT_FLAG_DEBUG_BIT";
|
||||
case 0x4:
|
||||
return "GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT";
|
||||
case 0x10:
|
||||
return "GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT";
|
||||
default:
|
||||
return UnknownGLenumToString(value);
|
||||
}
|
||||
|
@ -1173,6 +1175,8 @@ const char *GLenumToString(GLenumGroup enumGroup, unsigned int value)
|
|||
return "GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES";
|
||||
case 0x8BE7:
|
||||
return "GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT";
|
||||
case 0x8BFA:
|
||||
return "GL_TEXTURE_PROTECTED_EXT";
|
||||
case 0x8C10:
|
||||
return "GL_TEXTURE_RED_TYPE";
|
||||
case 0x8C11:
|
||||
|
|
|
@ -369,6 +369,9 @@ void QueryTexParameterBase(const Context *context,
|
|||
*params = CastFromGLintStateValue<ParamType>(
|
||||
pname, texture->getRequiredTextureImageUnits(context));
|
||||
break;
|
||||
case GL_TEXTURE_PROTECTED_EXT:
|
||||
*params = CastFromGLintStateValue<ParamType>(pname, texture->hasProtectedContent());
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -479,6 +482,9 @@ void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const
|
|||
texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized
|
||||
: InitState::MayNeedInit);
|
||||
break;
|
||||
case GL_TEXTURE_PROTECTED_EXT:
|
||||
texture->setProtectedContent(context, (params[0] == GL_TRUE));
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
@ -2193,6 +2199,10 @@ angle::Result SetMemoryObjectParameteriv(const Context *context,
|
|||
ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
|
||||
break;
|
||||
|
||||
case GL_PROTECTED_MEMORY_OBJECT_EXT:
|
||||
ANGLE_TRY(memoryObject->setProtectedMemory(context, ConvertToBool(params[0])));
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -2208,6 +2218,10 @@ void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname
|
|||
*params = memoryObject->isDedicatedMemory();
|
||||
break;
|
||||
|
||||
case GL_PROTECTED_MEMORY_OBJECT_EXT:
|
||||
*params = memoryObject->isProtectedMemory();
|
||||
break;
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ class ExternalImageSiblingImpl : public FramebufferAttachmentObjectImpl
|
|||
virtual bool isRenderable(const gl::Context *context) const = 0;
|
||||
virtual bool isTexturable(const gl::Context *context) const = 0;
|
||||
virtual bool isYUV() const = 0;
|
||||
virtual bool hasProtectedContent() const = 0;
|
||||
virtual gl::Extents getSize() const = 0;
|
||||
virtual size_t getSamples() const = 0;
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@ class MemoryObjectImpl : angle::NonCopyable
|
|||
virtual void onDestroy(const gl::Context *context) = 0;
|
||||
|
||||
virtual angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) = 0;
|
||||
virtual angle::Result setProtectedMemory(const gl::Context *context, bool protectedMemory) = 0;
|
||||
|
||||
virtual angle::Result importFd(gl::Context *context,
|
||||
GLuint64 size,
|
||||
|
|
|
@ -81,6 +81,11 @@ bool ExternalImageSiblingImpl11::isYUV() const
|
|||
return mYUV;
|
||||
}
|
||||
|
||||
bool ExternalImageSiblingImpl11::hasProtectedContent() const
|
||||
{
|
||||
return mHasProtectedContent;
|
||||
}
|
||||
|
||||
gl::Extents ExternalImageSiblingImpl11::getSize() const
|
||||
{
|
||||
return gl::Extents(mWidth, mHeight, 1);
|
||||
|
|
|
@ -30,6 +30,7 @@ class ExternalImageSiblingImpl11 : public ExternalImageSiblingImpl
|
|||
bool isRenderable(const gl::Context *context) const override;
|
||||
bool isTexturable(const gl::Context *context) const override;
|
||||
bool isYUV() const override;
|
||||
bool hasProtectedContent() const override;
|
||||
gl::Extents getSize() const override;
|
||||
size_t getSamples() const override;
|
||||
|
||||
|
@ -51,15 +52,16 @@ class ExternalImageSiblingImpl11 : public ExternalImageSiblingImpl
|
|||
|
||||
TextureHelper11 mTexture;
|
||||
|
||||
gl::Format mFormat = gl::Format::Invalid();
|
||||
bool mIsRenderable = false;
|
||||
bool mIsTexturable = false;
|
||||
bool mIsTextureArray = false;
|
||||
bool mYUV = false;
|
||||
EGLint mWidth = 0;
|
||||
EGLint mHeight = 0;
|
||||
GLsizei mSamples = 0;
|
||||
UINT mArraySlice = 0;
|
||||
gl::Format mFormat = gl::Format::Invalid();
|
||||
bool mIsRenderable = false;
|
||||
bool mIsTexturable = false;
|
||||
bool mIsTextureArray = false;
|
||||
bool mYUV = false;
|
||||
bool mHasProtectedContent = false;
|
||||
EGLint mWidth = 0;
|
||||
EGLint mHeight = 0;
|
||||
GLsizei mSamples = 0;
|
||||
UINT mArraySlice = 0;
|
||||
|
||||
std::unique_ptr<RenderTargetD3D> mRenderTarget;
|
||||
};
|
||||
|
|
|
@ -40,6 +40,16 @@ angle::Result MemoryObjectGL::setDedicatedMemory(const gl::Context *context, boo
|
|||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result MemoryObjectGL::setProtectedMemory(const gl::Context *context, bool protectedMemory)
|
||||
{
|
||||
const FunctionsGL *functions = GetFunctionsGL(context);
|
||||
|
||||
GLint params = gl::ConvertToGLBoolean(protectedMemory);
|
||||
ANGLE_GL_TRY(context, functions->memoryObjectParameterivEXT(
|
||||
mMemoryObject, GL_PROTECTED_MEMORY_OBJECT_EXT, ¶ms));
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result MemoryObjectGL::importFd(gl::Context *context,
|
||||
GLuint64 size,
|
||||
gl::HandleType handleType,
|
||||
|
|
|
@ -22,6 +22,7 @@ class MemoryObjectGL : public MemoryObjectImpl
|
|||
void onDestroy(const gl::Context *context) override;
|
||||
|
||||
angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) override;
|
||||
angle::Result setProtectedMemory(const gl::Context *context, bool protectedMemory) override;
|
||||
|
||||
angle::Result importFd(gl::Context *context,
|
||||
GLuint64 size,
|
||||
|
|
|
@ -74,13 +74,14 @@ GLenum FourCCFormatToGLInternalFormat(int format, bool *isYUV)
|
|||
namespace rx
|
||||
{
|
||||
DmaBufImageSiblingEGL::DmaBufImageSiblingEGL(const egl::AttributeMap &attribs)
|
||||
: mAttribs(attribs), mFormat(GL_NONE), mYUV(false)
|
||||
: mAttribs(attribs), mFormat(GL_NONE), mYUV(false), mHasProtectedContent(false)
|
||||
{
|
||||
ASSERT(mAttribs.contains(EGL_WIDTH));
|
||||
mSize.width = mAttribs.getAsInt(EGL_WIDTH);
|
||||
ASSERT(mAttribs.contains(EGL_HEIGHT));
|
||||
mSize.height = mAttribs.getAsInt(EGL_HEIGHT);
|
||||
mSize.depth = 1;
|
||||
mSize.height = mAttribs.getAsInt(EGL_HEIGHT);
|
||||
mSize.depth = 1;
|
||||
mHasProtectedContent = mAttribs.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != 0;
|
||||
|
||||
int fourCCFormat = mAttribs.getAsInt(EGL_LINUX_DRM_FOURCC_EXT);
|
||||
mFormat = gl::Format(FourCCFormatToGLInternalFormat(fourCCFormat, &mYUV));
|
||||
|
@ -113,6 +114,11 @@ bool DmaBufImageSiblingEGL::isYUV() const
|
|||
return mYUV;
|
||||
}
|
||||
|
||||
bool DmaBufImageSiblingEGL::hasProtectedContent() const
|
||||
{
|
||||
return mHasProtectedContent;
|
||||
}
|
||||
|
||||
gl::Extents DmaBufImageSiblingEGL::getSize() const
|
||||
{
|
||||
return mSize;
|
||||
|
@ -132,6 +138,7 @@ void DmaBufImageSiblingEGL::getImageCreationAttributes(std::vector<EGLint> *outA
|
|||
{
|
||||
EGLenum kForwardedAttribs[] = {EGL_WIDTH,
|
||||
EGL_HEIGHT,
|
||||
EGL_PROTECTED_CONTENT_EXT,
|
||||
EGL_LINUX_DRM_FOURCC_EXT,
|
||||
EGL_DMA_BUF_PLANE0_FD_EXT,
|
||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT,
|
||||
|
|
|
@ -28,6 +28,7 @@ class DmaBufImageSiblingEGL : public ExternalImageSiblingEGL
|
|||
bool isRenderable(const gl::Context *context) const override;
|
||||
bool isTexturable(const gl::Context *context) const override;
|
||||
bool isYUV() const override;
|
||||
bool hasProtectedContent() const override;
|
||||
gl::Extents getSize() const override;
|
||||
size_t getSamples() const override;
|
||||
|
||||
|
@ -40,6 +41,7 @@ class DmaBufImageSiblingEGL : public ExternalImageSiblingEGL
|
|||
gl::Extents mSize;
|
||||
gl::Format mFormat;
|
||||
bool mYUV;
|
||||
bool mHasProtectedContent;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
|
|
|
@ -21,11 +21,13 @@ NativeBufferImageSiblingAndroid::~NativeBufferImageSiblingAndroid() {}
|
|||
egl::Error NativeBufferImageSiblingAndroid::initialize(const egl::Display *display)
|
||||
{
|
||||
int pixelFormat = 0;
|
||||
uint64_t usage = 0;
|
||||
angle::android::GetANativeWindowBufferProperties(
|
||||
angle::android::ClientBufferToANativeWindowBuffer(mBuffer), &mSize.width, &mSize.height,
|
||||
&mSize.depth, &pixelFormat);
|
||||
&mSize.depth, &pixelFormat, &usage);
|
||||
mFormat = gl::Format(angle::android::NativePixelFormatToGLInternalFormat(pixelFormat));
|
||||
mYUV = angle::android::NativePixelFormatIsYUV(pixelFormat);
|
||||
mHasProtectedContent = (usage & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) != 0;
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
@ -50,6 +52,11 @@ bool NativeBufferImageSiblingAndroid::isYUV() const
|
|||
return mYUV;
|
||||
}
|
||||
|
||||
bool NativeBufferImageSiblingAndroid::hasProtectedContent() const
|
||||
{
|
||||
return mHasProtectedContent;
|
||||
}
|
||||
|
||||
gl::Extents NativeBufferImageSiblingAndroid::getSize() const
|
||||
{
|
||||
return mSize;
|
||||
|
|
|
@ -28,6 +28,7 @@ class NativeBufferImageSiblingAndroid : public ExternalImageSiblingEGL
|
|||
bool isRenderable(const gl::Context *context) const override;
|
||||
bool isTexturable(const gl::Context *context) const override;
|
||||
bool isYUV() const override;
|
||||
bool hasProtectedContent() const override;
|
||||
gl::Extents getSize() const override;
|
||||
size_t getSamples() const override;
|
||||
|
||||
|
@ -39,6 +40,7 @@ class NativeBufferImageSiblingAndroid : public ExternalImageSiblingEGL
|
|||
gl::Extents mSize;
|
||||
gl::Format mFormat;
|
||||
bool mYUV;
|
||||
bool mHasProtectedContent;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
|
|
|
@ -37,6 +37,7 @@ class TextureImageSiblingMtl : public ExternalImageSiblingImpl
|
|||
size_t getSamples() const override;
|
||||
|
||||
bool isYUV() const override;
|
||||
bool hasProtectedContent() const override;
|
||||
|
||||
const mtl::TextureRef &getTexture() const { return mNativeTexture; }
|
||||
const mtl::Format &getFormatMtl() const { return mFormat; }
|
||||
|
|
|
@ -118,6 +118,11 @@ bool TextureImageSiblingMtl::isYUV() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TextureImageSiblingMtl::hasProtectedContent() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ImageMtl implementation
|
||||
ImageMtl::ImageMtl(const egl::ImageState &state, const gl::Context *context) : ImageImpl(state) {}
|
||||
|
||||
|
|
|
@ -101,6 +101,12 @@ angle::Result MemoryObjectVk::setDedicatedMemory(const gl::Context *context, boo
|
|||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result MemoryObjectVk::setProtectedMemory(const gl::Context *context, bool protectedMemory)
|
||||
{
|
||||
mProtectedMemory = protectedMemory;
|
||||
return angle::Result::Continue;
|
||||
}
|
||||
|
||||
angle::Result MemoryObjectVk::importFd(gl::Context *context,
|
||||
GLuint64 size,
|
||||
gl::HandleType handleType,
|
||||
|
@ -204,11 +210,12 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
|
|||
// ANGLE_external_objects_flags allows create flags to be specified by the application instead
|
||||
// of getting defaulted to zero. Note that the GL enum values constituting the bits of
|
||||
// |createFlags| are identical to their corresponding Vulkan value.
|
||||
ANGLE_TRY(image->initExternal(contextVk, type, vkExtents, vkFormat, 1, imageUsageFlags,
|
||||
createFlags, vk::ImageLayout::Undefined,
|
||||
&externalMemoryImageCreateInfo, gl::LevelIndex(0),
|
||||
static_cast<uint32_t>(levels), layerCount,
|
||||
contextVk->isRobustResourceInitEnabled(), nullptr, false));
|
||||
bool hasProtectedContent = mProtectedMemory;
|
||||
ANGLE_TRY(image->initExternal(
|
||||
contextVk, type, vkExtents, vkFormat, 1, imageUsageFlags, createFlags,
|
||||
vk::ImageLayout::Undefined, &externalMemoryImageCreateInfo, gl::LevelIndex(0),
|
||||
static_cast<uint32_t>(levels), layerCount, contextVk->isRobustResourceInitEnabled(),
|
||||
nullptr, hasProtectedContent));
|
||||
|
||||
VkMemoryRequirements externalMemoryRequirements;
|
||||
image->getImage().getMemoryRequirements(renderer->getDevice(), &externalMemoryRequirements);
|
||||
|
@ -252,7 +259,7 @@ angle::Result MemoryObjectVk::createImage(ContextVk *contextVk,
|
|||
ASSERT(offset == 0);
|
||||
ASSERT(externalMemoryRequirements.size == mSize);
|
||||
|
||||
VkMemoryPropertyFlags flags = 0;
|
||||
VkMemoryPropertyFlags flags = hasProtectedContent ? VK_MEMORY_PROPERTY_PROTECTED_BIT : 0;
|
||||
ANGLE_TRY(image->initExternalMemory(contextVk, renderer->getMemoryProperties(),
|
||||
externalMemoryRequirements, nullptr, importMemoryInfo,
|
||||
renderer->getQueueFamilyIndex(), flags));
|
||||
|
|
|
@ -24,6 +24,7 @@ class MemoryObjectVk : public MemoryObjectImpl
|
|||
void onDestroy(const gl::Context *context) override;
|
||||
|
||||
angle::Result setDedicatedMemory(const gl::Context *context, bool dedicatedMemory) override;
|
||||
angle::Result setProtectedMemory(const gl::Context *context, bool protectedMemory) override;
|
||||
|
||||
angle::Result importFd(gl::Context *context,
|
||||
GLuint64 size,
|
||||
|
@ -52,6 +53,7 @@ class MemoryObjectVk : public MemoryObjectImpl
|
|||
|
||||
// Imported memory object was a dedicated allocation.
|
||||
bool mDedicatedMemory = false;
|
||||
bool mProtectedMemory = false;
|
||||
|
||||
GLuint64 mSize = 0;
|
||||
gl::HandleType mHandleType = gl::HandleType::InvalidEnum;
|
||||
|
|
|
@ -1008,10 +1008,10 @@ angle::Result TextureVk::copySubImageImplWithTransfer(ContextVk *contextVk,
|
|||
std::unique_ptr<vk::RefCounted<vk::ImageHelper>> stagingImage;
|
||||
stagingImage = std::make_unique<vk::RefCounted<vk::ImageHelper>>();
|
||||
|
||||
ANGLE_TRY(
|
||||
stagingImage->get().init2DStaging(contextVk, false, renderer->getMemoryProperties(),
|
||||
gl::Extents(sourceBox.width, sourceBox.height, 1),
|
||||
destFormat, kTransferStagingImageFlags, layerCount));
|
||||
ANGLE_TRY(stagingImage->get().init2DStaging(
|
||||
contextVk, mState.hasProtectedContent(), renderer->getMemoryProperties(),
|
||||
gl::Extents(sourceBox.width, sourceBox.height, 1), destFormat,
|
||||
kTransferStagingImageFlags, layerCount));
|
||||
|
||||
access.onImageTransferWrite(gl::LevelIndex(0), 1, 0, layerCount, VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
&stagingImage->get());
|
||||
|
@ -1159,10 +1159,10 @@ angle::Result TextureVk::copySubImageImplWithDraw(ContextVk *contextVk,
|
|||
std::unique_ptr<vk::RefCounted<vk::ImageHelper>> stagingImage;
|
||||
stagingImage = std::make_unique<vk::RefCounted<vk::ImageHelper>>();
|
||||
|
||||
ANGLE_TRY(
|
||||
stagingImage->get().init2DStaging(contextVk, false, renderer->getMemoryProperties(),
|
||||
gl::Extents(sourceBox.width, sourceBox.height, 1),
|
||||
destFormat, kDrawStagingImageFlags, layerCount));
|
||||
ANGLE_TRY(stagingImage->get().init2DStaging(
|
||||
contextVk, mState.hasProtectedContent(), renderer->getMemoryProperties(),
|
||||
gl::Extents(sourceBox.width, sourceBox.height, 1), destFormat, kDrawStagingImageFlags,
|
||||
layerCount));
|
||||
|
||||
params.destOffset[0] = 0;
|
||||
params.destOffset[1] = 0;
|
||||
|
@ -1987,10 +1987,10 @@ angle::Result TextureVk::copyAndStageImageData(ContextVk *contextVk,
|
|||
const uint32_t levelCount = srcImage->getLevelCount();
|
||||
const uint32_t layerCount = srcImage->getLayerCount();
|
||||
|
||||
ANGLE_TRY(stagingImage->get().initStaging(contextVk, false, renderer->getMemoryProperties(),
|
||||
srcImage->getType(), srcImage->getExtents(),
|
||||
srcImage->getFormat(), srcImage->getSamples(),
|
||||
kTransferStagingImageFlags, levelCount, layerCount));
|
||||
ANGLE_TRY(stagingImage->get().initStaging(
|
||||
contextVk, mState.hasProtectedContent(), renderer->getMemoryProperties(),
|
||||
srcImage->getType(), srcImage->getExtents(), srcImage->getFormat(), srcImage->getSamples(),
|
||||
kTransferStagingImageFlags, levelCount, layerCount));
|
||||
|
||||
// Copy the src image wholly into the staging image
|
||||
const VkImageAspectFlags aspectFlags = srcImage->getAspectFlags();
|
||||
|
@ -2196,8 +2196,8 @@ angle::Result TextureVk::getAttachmentRenderTarget(const gl::Context *context,
|
|||
|
||||
// Create the implicit multisampled image.
|
||||
ANGLE_TRY(multisampledImage->initImplicitMultisampledRenderToTexture(
|
||||
contextVk, false, renderer->getMemoryProperties(), mState.getType(), samples, *mImage,
|
||||
useRobustInit));
|
||||
contextVk, mState.hasProtectedContent(), renderer->getMemoryProperties(),
|
||||
mState.getType(), samples, *mImage, useRobustInit));
|
||||
}
|
||||
|
||||
// Don't flush staged updates here. We'll handle that in FramebufferVk so it can defer clears.
|
||||
|
@ -2793,17 +2793,28 @@ angle::Result TextureVk::initImage(ContextVk *contextVk,
|
|||
gl_vk::GetExtentsAndLayerCount(mState.getType(), firstLevelExtents, &vkExtent, &layerCount);
|
||||
GLint samples = mState.getBaseLevelDesc().samples ? mState.getBaseLevelDesc().samples : 1;
|
||||
|
||||
if (mState.hasProtectedContent())
|
||||
{
|
||||
mImageCreateFlags |= VK_IMAGE_CREATE_PROTECTED_BIT;
|
||||
}
|
||||
|
||||
bool imageFormatListEnabled = false;
|
||||
ANGLE_TRY(mImage->initExternal(
|
||||
contextVk, mState.getType(), vkExtent, format, samples, mImageUsageFlags, mImageCreateFlags,
|
||||
vk::ImageLayout::Undefined, nullptr, gl::LevelIndex(firstLevel), levelCount, layerCount,
|
||||
contextVk->isRobustResourceInitEnabled(), &imageFormatListEnabled, false));
|
||||
ANGLE_TRY(mImage->initExternal(contextVk, mState.getType(), vkExtent, format, samples,
|
||||
mImageUsageFlags, mImageCreateFlags, vk::ImageLayout::Undefined,
|
||||
nullptr, gl::LevelIndex(firstLevel), levelCount, layerCount,
|
||||
contextVk->isRobustResourceInitEnabled(),
|
||||
&imageFormatListEnabled, mState.hasProtectedContent()));
|
||||
|
||||
mRequiresMutableStorage = (mImageCreateFlags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) != 0;
|
||||
|
||||
const VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
if (mState.hasProtectedContent())
|
||||
{
|
||||
flags |= VK_MEMORY_PROPERTY_PROTECTED_BIT;
|
||||
}
|
||||
|
||||
ANGLE_TRY(mImage->initMemory(contextVk, false, renderer->getMemoryProperties(), flags));
|
||||
ANGLE_TRY(mImage->initMemory(contextVk, mState.hasProtectedContent(),
|
||||
renderer->getMemoryProperties(), flags));
|
||||
|
||||
const uint32_t viewLevelCount =
|
||||
mState.getImmutableFormat() ? getMipLevelCount(ImageMipLevels::EnabledLevels) : levelCount;
|
||||
|
|
|
@ -98,8 +98,8 @@ egl::Error DisplayVkAndroid::validateImageClientBuffer(const gl::Context *contex
|
|||
switch (target)
|
||||
{
|
||||
case EGL_NATIVE_BUFFER_ANDROID:
|
||||
return HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(mRenderer,
|
||||
clientBuffer);
|
||||
return HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(
|
||||
mRenderer, clientBuffer, attribs);
|
||||
|
||||
default:
|
||||
return DisplayVk::validateImageClientBuffer(context, target, clientBuffer, attribs);
|
||||
|
|
|
@ -87,8 +87,10 @@ HardwareBufferImageSiblingVkAndroid::HardwareBufferImageSiblingVkAndroid(EGLClie
|
|||
HardwareBufferImageSiblingVkAndroid::~HardwareBufferImageSiblingVkAndroid() {}
|
||||
|
||||
// Static
|
||||
egl::Error HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(RendererVk *renderer,
|
||||
EGLClientBuffer buffer)
|
||||
egl::Error HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(
|
||||
RendererVk *renderer,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs)
|
||||
{
|
||||
struct ANativeWindowBuffer *windowBuffer =
|
||||
angle::android::ClientBufferToANativeWindowBuffer(buffer);
|
||||
|
@ -133,6 +135,23 @@ egl::Error HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(RendererV
|
|||
}
|
||||
}
|
||||
|
||||
if (attribs.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) == EGL_TRUE)
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int depth = 0;
|
||||
int pixelFormat = 0;
|
||||
uint64_t usage = 0;
|
||||
angle::android::GetANativeWindowBufferProperties(windowBuffer, &width, &height, &depth,
|
||||
&pixelFormat, &usage);
|
||||
if ((usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) == 0)
|
||||
{
|
||||
return egl::EglBadAccess()
|
||||
<< "EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
|
||||
"of EGLCleintBuffer.";
|
||||
}
|
||||
}
|
||||
|
||||
return egl::NoError();
|
||||
}
|
||||
|
||||
|
@ -191,7 +210,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
|
|||
|
||||
int pixelFormat = 0;
|
||||
angle::android::GetANativeWindowBufferProperties(windowBuffer, &mSize.width, &mSize.height,
|
||||
&mSize.depth, &pixelFormat);
|
||||
&mSize.depth, &pixelFormat, &mUsage);
|
||||
GLenum internalFormat = angle::android::NativePixelFormatToGLInternalFormat(pixelFormat);
|
||||
mFormat = gl::Format(internalFormat);
|
||||
|
||||
|
@ -259,12 +278,17 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
|
|||
bool robustInitEnabled = false;
|
||||
|
||||
mImage->setTilingMode(imageTilingMode);
|
||||
VkImageCreateFlags imageCreateFlags = vk::kVkImageCreateFlagsNone;
|
||||
if (hasProtectedContent())
|
||||
{
|
||||
imageCreateFlags |= VK_IMAGE_CREATE_PROTECTED_BIT;
|
||||
}
|
||||
ANGLE_TRY(mImage->initExternal(
|
||||
displayVk, gl::TextureType::_2D, vkExtents,
|
||||
bufferFormatProperties.format == VK_FORMAT_UNDEFINED ? externalVkFormat : vkFormat, 1,
|
||||
usage, vk::kVkImageCreateFlagsNone, vk::ImageLayout::ExternalPreInitialized,
|
||||
usage, imageCreateFlags, vk::ImageLayout::ExternalPreInitialized,
|
||||
&externalMemoryImageCreateInfo, gl::LevelIndex(0), 1, 1, robustInitEnabled, nullptr,
|
||||
false));
|
||||
hasProtectedContent()));
|
||||
|
||||
VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {};
|
||||
importHardwareBufferInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
|
||||
|
@ -281,7 +305,8 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
|
|||
externalMemoryRequirements.alignment = 0;
|
||||
externalMemoryRequirements.memoryTypeBits = bufferProperties.memoryTypeBits;
|
||||
|
||||
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
|
||||
(hasProtectedContent() ? VK_MEMORY_PROPERTY_PROTECTED_BIT : 0);
|
||||
if (bufferFormatProperties.format == VK_FORMAT_UNDEFINED)
|
||||
{
|
||||
// Note from Vulkan spec: Since GL_OES_EGL_image_external does not require the same sampling
|
||||
|
@ -360,6 +385,11 @@ bool HardwareBufferImageSiblingVkAndroid::isYUV() const
|
|||
return mYUV;
|
||||
}
|
||||
|
||||
bool HardwareBufferImageSiblingVkAndroid::hasProtectedContent() const
|
||||
{
|
||||
return ((mUsage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) != 0);
|
||||
}
|
||||
|
||||
gl::Extents HardwareBufferImageSiblingVkAndroid::getSize() const
|
||||
{
|
||||
return mSize;
|
||||
|
|
|
@ -21,7 +21,9 @@ class HardwareBufferImageSiblingVkAndroid : public ExternalImageSiblingVk
|
|||
HardwareBufferImageSiblingVkAndroid(EGLClientBuffer buffer);
|
||||
~HardwareBufferImageSiblingVkAndroid() override;
|
||||
|
||||
static egl::Error ValidateHardwareBuffer(RendererVk *renderer, EGLClientBuffer buffer);
|
||||
static egl::Error ValidateHardwareBuffer(RendererVk *renderer,
|
||||
EGLClientBuffer buffer,
|
||||
const egl::AttributeMap &attribs);
|
||||
|
||||
egl::Error initialize(const egl::Display *display) override;
|
||||
void onDestroy(const egl::Display *display) override;
|
||||
|
@ -31,6 +33,7 @@ class HardwareBufferImageSiblingVkAndroid : public ExternalImageSiblingVk
|
|||
bool isRenderable(const gl::Context *context) const override;
|
||||
bool isTexturable(const gl::Context *context) const override;
|
||||
bool isYUV() const override;
|
||||
bool hasProtectedContent() const override;
|
||||
gl::Extents getSize() const override;
|
||||
size_t getSamples() const override;
|
||||
|
||||
|
@ -49,6 +52,7 @@ class HardwareBufferImageSiblingVkAndroid : public ExternalImageSiblingVk
|
|||
bool mRenderable;
|
||||
bool mTextureable;
|
||||
bool mYUV;
|
||||
uint64_t mUsage;
|
||||
size_t mSamples;
|
||||
|
||||
vk::ImageHelper *mImage;
|
||||
|
|
|
@ -1072,6 +1072,9 @@ void RendererVk::ensureCapsInitialized() const
|
|||
// GL_ANGLE_yuv_internal_format
|
||||
mNativeExtensions.yuvInternalFormatANGLE =
|
||||
getFeatures().supportsYUVSamplerConversion.enabled && vk::CanSupportYuvInternalFormat(this);
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
mNativeExtensions.protectedTexturesEXT = mFeatures.supportsProtectedMemory.enabled;
|
||||
}
|
||||
|
||||
namespace vk
|
||||
|
|
|
@ -3240,6 +3240,16 @@ bool ValidateCreateImage(const ValidationContext *val,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool protectedContentAttrib =
|
||||
(attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
|
||||
if (protectedContentAttrib != texture->hasProtectedContent())
|
||||
{
|
||||
val->setError(EGL_BAD_PARAMETER,
|
||||
"EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
|
||||
"of target.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
|
||||
}
|
||||
break;
|
||||
|
@ -3301,6 +3311,16 @@ bool ValidateCreateImage(const ValidationContext *val,
|
|||
"zero.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool protectedContentAttrib =
|
||||
(attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
|
||||
if (protectedContentAttrib != texture->hasProtectedContent())
|
||||
{
|
||||
val->setError(EGL_BAD_PARAMETER,
|
||||
"EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
|
||||
"of target.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3355,6 +3375,16 @@ bool ValidateCreateImage(const ValidationContext *val,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool protectedContentAttrib =
|
||||
(attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
|
||||
if (protectedContentAttrib != texture->hasProtectedContent())
|
||||
{
|
||||
val->setError(EGL_BAD_PARAMETER,
|
||||
"EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
|
||||
"of target.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ANGLE_VALIDATION_TRY(ValidateCreateImageMipLevelCommon(val, context, texture, level));
|
||||
}
|
||||
break;
|
||||
|
@ -3396,6 +3426,16 @@ bool ValidateCreateImage(const ValidationContext *val,
|
|||
val->setError(EGL_BAD_PARAMETER, "target renderbuffer cannot be multisampled.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool protectedContentAttrib =
|
||||
(attributes.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE) != EGL_FALSE);
|
||||
if (protectedContentAttrib != renderbuffer->hasProtectedContent())
|
||||
{
|
||||
val->setError(EGL_BAD_ACCESS,
|
||||
"EGL_PROTECTED_CONTENT_EXT attribute does not match protected state "
|
||||
"of target.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -4583,6 +4583,13 @@ bool ValidateEGLImageTargetTexture2DOES(const Context *context,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (imageObject->hasProtectedContent() != context->getState().hasProtectedContent())
|
||||
{
|
||||
context->validationError(GL_INVALID_OPERATION,
|
||||
"Mismatch between Image and Context Protected Content state");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4621,6 +4628,13 @@ bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (imageObject->hasProtectedContent() != context->getState().hasProtectedContent())
|
||||
{
|
||||
context->validationError(GL_INVALID_OPERATION,
|
||||
"Mismatch between Image and Context Protected Content state");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6549,6 +6563,14 @@ bool ValidateGetTexParameterBase(const Context *context,
|
|||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_PROTECTED_EXT:
|
||||
if (!context->getExtensions().protectedTexturesEXT)
|
||||
{
|
||||
context->validationError(GL_INVALID_ENUM, kProtectedTexturesExtensionRequired);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
context->validationError(GL_INVALID_ENUM, kEnumNotSupported);
|
||||
return false;
|
||||
|
@ -7251,7 +7273,20 @@ bool ValidateTexParameterBase(const Context *context,
|
|||
kRobustResourceInitializationExtensionRequired);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case GL_TEXTURE_PROTECTED_EXT:
|
||||
if (!context->getExtensions().protectedTexturesEXT)
|
||||
{
|
||||
context->validationError(GL_INVALID_ENUM, kProtectedTexturesExtensionRequired);
|
||||
return false;
|
||||
}
|
||||
if (ConvertToBool(params[0]) != context->getState().hasProtectedContent())
|
||||
{
|
||||
context->validationError(GL_INVALID_OPERATION,
|
||||
"Protected Texture must match Protected Context");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -72,6 +72,14 @@ bool IsValidMemoryObjectParamater(const Context *context, GLenum pname)
|
|||
case GL_DEDICATED_MEMORY_OBJECT_EXT:
|
||||
return true;
|
||||
|
||||
case GL_PROTECTED_MEMORY_OBJECT_EXT:
|
||||
if (!context->getExtensions().protectedTexturesEXT)
|
||||
{
|
||||
context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1052,6 +1052,8 @@ bool ValidatePrimitiveBoundingBoxEXT(const Context *context,
|
|||
GLfloat maxZ,
|
||||
GLfloat maxW);
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
|
||||
// GL_EXT_read_format_bgra
|
||||
|
||||
// GL_EXT_robustness
|
||||
|
|
|
@ -5483,6 +5483,8 @@ void GL_APIENTRY GL_PrimitiveBoundingBoxEXT(GLfloat minX,
|
|||
}
|
||||
}
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
|
||||
// GL_EXT_read_format_bgra
|
||||
|
||||
// GL_EXT_robustness
|
||||
|
|
|
@ -893,6 +893,8 @@ ANGLE_EXPORT void GL_APIENTRY GL_PrimitiveBoundingBoxEXT(GLfloat minX,
|
|||
GLfloat maxZ,
|
||||
GLfloat maxW);
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
|
||||
// GL_EXT_read_format_bgra
|
||||
|
||||
// GL_EXT_robustness
|
||||
|
|
|
@ -4227,6 +4227,8 @@ void GL_APIENTRY glPrimitiveBoundingBoxEXT(GLfloat minX,
|
|||
return GL_PrimitiveBoundingBoxEXT(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
|
||||
}
|
||||
|
||||
// GL_EXT_protected_textures
|
||||
|
||||
// GL_EXT_read_format_bgra
|
||||
|
||||
// GL_EXT_robustness
|
||||
|
|
|
@ -716,6 +716,8 @@ EXPORTS
|
|||
; GL_EXT_primitive_bounding_box
|
||||
glPrimitiveBoundingBoxEXT
|
||||
|
||||
; GL_EXT_protected_textures
|
||||
|
||||
; GL_EXT_read_format_bgra
|
||||
|
||||
; GL_EXT_robustness
|
||||
|
|
|
@ -716,6 +716,8 @@ EXPORTS
|
|||
; GL_EXT_primitive_bounding_box
|
||||
glPrimitiveBoundingBoxEXT
|
||||
|
||||
; GL_EXT_protected_textures
|
||||
|
||||
; GL_EXT_read_format_bgra
|
||||
|
||||
; GL_EXT_robustness
|
||||
|
|
|
@ -716,6 +716,8 @@ EXPORTS
|
|||
; GL_EXT_primitive_bounding_box
|
||||
glPrimitiveBoundingBoxEXT
|
||||
|
||||
; GL_EXT_protected_textures
|
||||
|
||||
; GL_EXT_read_format_bgra
|
||||
|
||||
; GL_EXT_robustness
|
||||
|
|
|
@ -63,6 +63,8 @@ class EGLProtectedContentTest : public ANGLETest
|
|||
clientVersion,
|
||||
EGL_SURFACE_TYPE,
|
||||
(EGL_PBUFFER_BIT | EGL_WINDOW_BIT),
|
||||
EGL_BIND_TO_TEXTURE_RGBA,
|
||||
EGL_TRUE,
|
||||
EGL_NONE};
|
||||
|
||||
EGLint count = 0;
|
||||
|
@ -88,10 +90,27 @@ class EGLProtectedContentTest : public ANGLETest
|
|||
|
||||
bool createPbufferSurface(EGLBoolean isProtected, EGLConfig config, EGLSurface *surface)
|
||||
{
|
||||
bool result = false;
|
||||
EGLint attribsProtected[] = {
|
||||
EGL_WIDTH, kWidth, EGL_HEIGHT, kHeight, EGL_PROTECTED_CONTENT_EXT, EGL_TRUE, EGL_NONE};
|
||||
EGLint attribsUnProtected[] = {EGL_WIDTH, kWidth, EGL_HEIGHT, kHeight, EGL_NONE};
|
||||
bool result = false;
|
||||
EGLint attribsProtected[] = {EGL_WIDTH,
|
||||
kWidth,
|
||||
EGL_HEIGHT,
|
||||
kHeight,
|
||||
EGL_TEXTURE_FORMAT,
|
||||
EGL_TEXTURE_RGBA,
|
||||
EGL_TEXTURE_TARGET,
|
||||
EGL_TEXTURE_2D,
|
||||
EGL_PROTECTED_CONTENT_EXT,
|
||||
EGL_TRUE,
|
||||
EGL_NONE};
|
||||
EGLint attribsUnProtected[] = {EGL_WIDTH,
|
||||
kWidth,
|
||||
EGL_HEIGHT,
|
||||
kHeight,
|
||||
EGL_TEXTURE_FORMAT,
|
||||
EGL_TEXTURE_RGBA,
|
||||
EGL_TEXTURE_TARGET,
|
||||
EGL_TEXTURE_2D,
|
||||
EGL_NONE};
|
||||
|
||||
*surface = eglCreatePbufferSurface(mDisplay, config,
|
||||
(isProtected ? attribsProtected : attribsUnProtected));
|
||||
|
@ -116,8 +135,231 @@ class EGLProtectedContentTest : public ANGLETest
|
|||
return result;
|
||||
}
|
||||
|
||||
void PbufferTest(bool isProtectedContext, bool isProtectedSurface);
|
||||
void WindowTest(bool isProtectedContext, bool isProtectedSurface);
|
||||
bool createImage(EGLBoolean isProtected,
|
||||
EGLContext context,
|
||||
EGLenum target,
|
||||
EGLClientBuffer buffer,
|
||||
EGLImage *image)
|
||||
{
|
||||
bool result = false;
|
||||
EGLAttrib attribsProtected[] = {EGL_PROTECTED_CONTENT_EXT, EGL_TRUE, EGL_NONE};
|
||||
|
||||
*image = eglCreateImage(mDisplay, context, target, buffer,
|
||||
(isProtected ? attribsProtected : nullptr));
|
||||
EXPECT_EGL_SUCCESS();
|
||||
result = (*image != EGL_NO_SURFACE);
|
||||
EXPECT_TRUE(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool createTexture(EGLBoolean isProtected, GLuint *textureId)
|
||||
{
|
||||
bool result = false;
|
||||
GLuint texture = 0;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
if (isProtected)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_PROTECTED_EXT, GL_TRUE);
|
||||
// GL_INVALID_OPERATION expected when context is not protected too.
|
||||
GLenum error = glGetError();
|
||||
if (error == GL_INVALID_OPERATION)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
result = (texture != 0);
|
||||
EXPECT_TRUE(result);
|
||||
*textureId = texture;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool createTextureFromImage(EGLImage image, GLuint *textureId)
|
||||
{
|
||||
bool result = false;
|
||||
GLuint texture = 0;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
result = (texture != 0);
|
||||
EXPECT_TRUE(result);
|
||||
*textureId = texture;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool createTextureFromPbuffer(EGLSurface pBuffer, GLuint *textureId)
|
||||
{
|
||||
bool result = false;
|
||||
GLuint texture = 0;
|
||||
glGenTextures(1, &texture);
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
EXPECT_TRUE(texture != 0);
|
||||
result = eglBindTexImage(mDisplay, pBuffer, EGL_BACK_BUFFER);
|
||||
glViewport(0, 0, kWidth, kHeight);
|
||||
*textureId = texture;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool fillTexture(GLuint textureId, GLColor color)
|
||||
{
|
||||
GLuint pixels[kWidth * kHeight];
|
||||
for (uint32_t i = 0; i < (kWidth * kHeight); i++)
|
||||
{
|
||||
pixels[i] = *(GLuint *)(color.data());
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
(void *)pixels);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool renderTexture(GLuint textureId)
|
||||
{
|
||||
const char *kVertexShader = R"(
|
||||
precision highp float;
|
||||
attribute vec4 position;
|
||||
varying vec2 texcoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position.xy, 0.0, 1.0);
|
||||
texcoord = (position.xy * 0.5) + 0.5;
|
||||
}
|
||||
)";
|
||||
const char *kFragmentShader = R"(
|
||||
precision highp float;
|
||||
uniform sampler2D tex;
|
||||
varying vec2 texcoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(tex, texcoord);
|
||||
}
|
||||
)";
|
||||
|
||||
GLuint program = CompileProgram(kVertexShader, kFragmentShader);
|
||||
glUseProgram(program);
|
||||
glBindTexture(GL_TEXTURE_2D, textureId);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
GLint texture2DUniformLocation = glGetUniformLocation(program, "tex");
|
||||
glUniform1i(texture2DUniformLocation, 0);
|
||||
drawQuad(program, "position", 0.5f);
|
||||
glDeleteProgram(program);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool createRenderbuffer(GLuint *renderbuffer)
|
||||
{
|
||||
bool result = false;
|
||||
*renderbuffer = 0;
|
||||
glGenRenderbuffers(1, renderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, kWidth, kHeight);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
result = (*renderbuffer != 0);
|
||||
EXPECT_TRUE(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool createRenderbufferFromImage(EGLImage image, GLuint *renderbuffer)
|
||||
{
|
||||
bool result = false;
|
||||
*renderbuffer = 0;
|
||||
glGenRenderbuffers(1, renderbuffer);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
|
||||
glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image);
|
||||
EXPECT_GL_NO_ERROR();
|
||||
result = (*renderbuffer != 0);
|
||||
EXPECT_TRUE(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool createAndroidClientBuffer(bool useProtected,
|
||||
bool useRenderbuffer,
|
||||
bool useTexture,
|
||||
EGLClientBuffer *clientBuffer)
|
||||
{
|
||||
bool result = false;
|
||||
EGLint nativeBufferUsage =
|
||||
0 | (useProtected ? EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID : 0) |
|
||||
(useRenderbuffer ? EGL_NATIVE_BUFFER_USAGE_RENDERBUFFER_BIT_ANDROID : 0) |
|
||||
(useTexture ? EGL_NATIVE_BUFFER_USAGE_TEXTURE_BIT_ANDROID : 0);
|
||||
|
||||
EGLint attribs[] = {EGL_WIDTH,
|
||||
kWidth,
|
||||
EGL_HEIGHT,
|
||||
kHeight,
|
||||
EGL_RED_SIZE,
|
||||
8,
|
||||
EGL_GREEN_SIZE,
|
||||
8,
|
||||
EGL_BLUE_SIZE,
|
||||
8,
|
||||
EGL_ALPHA_SIZE,
|
||||
8,
|
||||
EGL_NATIVE_BUFFER_USAGE_ANDROID,
|
||||
nativeBufferUsage,
|
||||
EGL_NONE};
|
||||
|
||||
*clientBuffer = eglCreateNativeClientBufferANDROID(attribs);
|
||||
EXPECT_EGL_SUCCESS();
|
||||
result = (*clientBuffer != nullptr);
|
||||
EXPECT_TRUE(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void pbufferTest(bool isProtectedContext, bool isProtectedSurface);
|
||||
void windowTest(bool isProtectedContext, bool isProtectedSurface);
|
||||
void textureTest(bool isProtectedContext, bool isProtectedTexture);
|
||||
void textureFromImageTest(bool isProtectedContext, bool isProtectedTexture);
|
||||
void textureFromPbufferTest(bool isProtectedContext, bool isProtectedTexture);
|
||||
void textureFromAndroidNativeBufferTest(bool isProtectedContext, bool isProtectedTexture);
|
||||
|
||||
void checkSwapBuffersResult(const std::string color,
|
||||
bool isProtectedContext,
|
||||
bool isProtectedSurface)
|
||||
{
|
||||
std::this_thread::sleep_for(1s);
|
||||
if (isProtectedContext)
|
||||
{
|
||||
if (isProtectedSurface)
|
||||
{
|
||||
std::cout << "Operator should see color: " << color << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Operator should see color: BLACK" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isProtectedSurface)
|
||||
{
|
||||
std::cout << "Operator should see color: BLACK" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Operator should see color: " << color << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EGLDisplay mDisplay = EGL_NO_DISPLAY;
|
||||
EGLint mMajorVersion = 0;
|
||||
|
@ -125,15 +367,13 @@ class EGLProtectedContentTest : public ANGLETest
|
|||
static const EGLint kHeight = 16;
|
||||
};
|
||||
|
||||
void EGLProtectedContentTest::PbufferTest(bool isProtectedContext, bool isProtectedSurface)
|
||||
void EGLProtectedContentTest::pbufferTest(bool isProtectedContext, bool isProtectedSurface)
|
||||
{
|
||||
if (isProtectedContext || isProtectedSurface)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
}
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
|
||||
EGLConfig config = EGL_NO_CONFIG_KHR;
|
||||
EXPECT_TRUE(chooseConfig(&config));
|
||||
ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
|
||||
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
EXPECT_TRUE(createContext(isProtectedContext, config, &context));
|
||||
|
@ -151,6 +391,7 @@ void EGLProtectedContentTest::PbufferTest(bool isProtectedContext, bool isProtec
|
|||
|
||||
glFinish();
|
||||
ASSERT_GL_NO_ERROR() << "glFinish failed";
|
||||
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
|
||||
|
@ -165,18 +406,16 @@ void EGLProtectedContentTest::PbufferTest(bool isProtectedContext, bool isProtec
|
|||
// Unprotected context with Unprotected PbufferSurface
|
||||
TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedPbufferSurface)
|
||||
{
|
||||
PbufferTest(false, false);
|
||||
pbufferTest(false, false);
|
||||
}
|
||||
|
||||
void EGLProtectedContentTest::WindowTest(bool isProtectedContext, bool isProtectedSurface)
|
||||
void EGLProtectedContentTest::windowTest(bool isProtectedContext, bool isProtectedSurface)
|
||||
{
|
||||
if (isProtectedContext || isProtectedSurface)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
}
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
|
||||
EGLConfig config = EGL_NO_CONFIG_KHR;
|
||||
EXPECT_TRUE(chooseConfig(&config));
|
||||
ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
|
||||
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
EXPECT_TRUE(createContext(isProtectedContext, config, &context));
|
||||
|
@ -199,7 +438,7 @@ void EGLProtectedContentTest::WindowTest(bool isProtectedContext, bool isProtect
|
|||
ASSERT_GL_NO_ERROR() << "glClear failed";
|
||||
eglSwapBuffers(mDisplay, windowSurface);
|
||||
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
|
||||
std::this_thread::sleep_for(1s);
|
||||
checkSwapBuffersResult("RED", isProtectedContext, isProtectedSurface);
|
||||
|
||||
// Green
|
||||
glClearColor(0.0, 1.0, 0.0, 1.0);
|
||||
|
@ -207,7 +446,7 @@ void EGLProtectedContentTest::WindowTest(bool isProtectedContext, bool isProtect
|
|||
ASSERT_GL_NO_ERROR() << "glClear failed";
|
||||
eglSwapBuffers(mDisplay, windowSurface);
|
||||
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
|
||||
std::this_thread::sleep_for(1s);
|
||||
checkSwapBuffersResult("GREEN", isProtectedContext, isProtectedSurface);
|
||||
|
||||
// Blue
|
||||
glClearColor(0.0, 0.0, 1.0, 1.0);
|
||||
|
@ -215,7 +454,7 @@ void EGLProtectedContentTest::WindowTest(bool isProtectedContext, bool isProtect
|
|||
ASSERT_GL_NO_ERROR() << "glClear failed";
|
||||
eglSwapBuffers(mDisplay, windowSurface);
|
||||
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
|
||||
std::this_thread::sleep_for(1s);
|
||||
checkSwapBuffersResult("BLUE", isProtectedContext, isProtectedSurface);
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
|
||||
|
@ -232,15 +471,361 @@ void EGLProtectedContentTest::WindowTest(bool isProtectedContext, bool isProtect
|
|||
// Unprotected context with Unprotected WindowSurface
|
||||
TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedWindowSurface)
|
||||
{
|
||||
std::cout << "Operator should see RED, GREEN, BLUE on screen" << std::endl;
|
||||
WindowTest(false, false);
|
||||
windowTest(false, false);
|
||||
}
|
||||
|
||||
// Protected context with Protected WindowSurface
|
||||
TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedWindowSurface)
|
||||
{
|
||||
std::cout << "Operator should see RED, GREEN, BLUE on screen" << std::endl;
|
||||
WindowTest(true, true);
|
||||
windowTest(true, true);
|
||||
}
|
||||
|
||||
void EGLProtectedContentTest::textureTest(bool isProtectedContext, bool isProtectedTexture)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
|
||||
bool isProtectedSurface = isProtectedTexture;
|
||||
|
||||
EGLConfig config = EGL_NO_CONFIG_KHR;
|
||||
EXPECT_TRUE(chooseConfig(&config));
|
||||
ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
|
||||
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
EXPECT_TRUE(createContext(isProtectedContext, config, &context));
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
|
||||
|
||||
OSWindow *osWindow = OSWindow::New();
|
||||
osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
|
||||
EGLSurface windowSurface = EGL_NO_SURFACE;
|
||||
EGLBoolean createWinSurfaceResult = createWindowSurface(
|
||||
isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
|
||||
EXPECT_TRUE(createWinSurfaceResult);
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
|
||||
glViewport(0, 0, kWidth, kHeight);
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
|
||||
|
||||
if (IsGLExtensionEnabled("GL_EXT_protected_textures"))
|
||||
{
|
||||
GLuint texture = 0;
|
||||
bool result = createTexture(isProtectedTexture, &texture);
|
||||
if (isProtectedTexture && !isProtectedContext)
|
||||
{
|
||||
std::cout << "Can't create protected Texture for Unprotected Context" << std::endl;
|
||||
ASSERT_FALSE(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_TRUE(result);
|
||||
|
||||
EXPECT_TRUE(fillTexture(texture, GLColor::red));
|
||||
EXPECT_TRUE(renderTexture(texture));
|
||||
|
||||
eglSwapBuffers(mDisplay, windowSurface);
|
||||
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
|
||||
checkSwapBuffersResult("RED", isProtectedContext, isProtectedSurface);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Skipping tests, GL_EXT_protected_textures not supported" << std::endl;
|
||||
}
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
|
||||
|
||||
eglDestroySurface(mDisplay, windowSurface);
|
||||
windowSurface = EGL_NO_SURFACE;
|
||||
osWindow->destroy();
|
||||
OSWindow::Delete(&osWindow);
|
||||
|
||||
eglDestroyContext(mDisplay, context);
|
||||
context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
// Unprotected context with unprotected texture
|
||||
TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTexture)
|
||||
{
|
||||
textureTest(false, false);
|
||||
}
|
||||
|
||||
// Protected context with protected texture
|
||||
TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTexture)
|
||||
{
|
||||
textureTest(true, true);
|
||||
}
|
||||
|
||||
void EGLProtectedContentTest::textureFromImageTest(bool isProtectedContext, bool isProtectedTexture)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
|
||||
bool isProtectedSurface = isProtectedTexture;
|
||||
|
||||
EGLConfig config = EGL_NO_CONFIG_KHR;
|
||||
EXPECT_TRUE(chooseConfig(&config));
|
||||
ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
|
||||
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
EXPECT_TRUE(createContext(isProtectedContext, config, &context));
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
|
||||
|
||||
OSWindow *osWindow = OSWindow::New();
|
||||
osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
|
||||
EGLSurface windowSurface = EGL_NO_SURFACE;
|
||||
EGLBoolean createWinSurfaceResult = createWindowSurface(
|
||||
isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
|
||||
EXPECT_TRUE(createWinSurfaceResult);
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
|
||||
glViewport(0, 0, kWidth, kHeight);
|
||||
|
||||
if (IsGLExtensionEnabled("GL_OES_EGL_image") &&
|
||||
IsGLExtensionEnabled("GL_EXT_protected_textures"))
|
||||
{
|
||||
GLuint srcTexture = 0;
|
||||
if (isProtectedTexture && !isProtectedContext)
|
||||
{
|
||||
std::cout << "Can't create protected Texture for Unprotected Context, Skipping"
|
||||
<< std::endl;
|
||||
ASSERT_FALSE(createTexture(isProtectedTexture, &srcTexture));
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_TRUE(createTexture(isProtectedTexture, &srcTexture));
|
||||
EXPECT_TRUE(fillTexture(srcTexture, GLColor::red));
|
||||
|
||||
EGLImage image = EGL_NO_IMAGE;
|
||||
EXPECT_TRUE(createImage(isProtectedTexture, context, EGL_GL_TEXTURE_2D,
|
||||
(void *)(static_cast<intptr_t>(srcTexture)), &image));
|
||||
|
||||
GLuint dstTexture = 0;
|
||||
EXPECT_TRUE(createTextureFromImage(image, &dstTexture));
|
||||
EXPECT_TRUE(renderTexture(dstTexture));
|
||||
|
||||
eglSwapBuffers(mDisplay, windowSurface);
|
||||
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
|
||||
checkSwapBuffersResult("RED", isProtectedContext, isProtectedSurface);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTextures(1, &dstTexture);
|
||||
glDeleteTextures(1, &srcTexture);
|
||||
|
||||
eglDestroyImage(mDisplay, image);
|
||||
image = EGL_NO_IMAGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Skipping tests, GL_OES_EGL_image or GL_EXT_protected_textures not supported"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
|
||||
|
||||
eglDestroySurface(mDisplay, windowSurface);
|
||||
windowSurface = EGL_NO_SURFACE;
|
||||
osWindow->destroy();
|
||||
OSWindow::Delete(&osWindow);
|
||||
|
||||
eglDestroyContext(mDisplay, context);
|
||||
context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
// Unprotected context with unprotected texture from EGL image
|
||||
TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTextureFromImage)
|
||||
{
|
||||
textureFromImageTest(false, false);
|
||||
}
|
||||
|
||||
// Protected context with protected texture from EGL image
|
||||
TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTextureFromImage)
|
||||
{
|
||||
textureFromImageTest(true, true);
|
||||
}
|
||||
|
||||
void EGLProtectedContentTest::textureFromPbufferTest(bool isProtectedContext,
|
||||
bool isProtectedTexture)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
|
||||
bool isProtectedSurface = isProtectedTexture;
|
||||
|
||||
EGLConfig config = EGL_NO_CONFIG_KHR;
|
||||
EXPECT_TRUE(chooseConfig(&config));
|
||||
ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
|
||||
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
EXPECT_TRUE(createContext(isProtectedContext, config, &context));
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
|
||||
|
||||
EGLSurface pBufferSurface = EGL_NO_SURFACE;
|
||||
EXPECT_TRUE(createPbufferSurface(isProtectedSurface, config, &pBufferSurface));
|
||||
ASSERT_EGL_SUCCESS() << "eglCreatePbufferSurface failed.";
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, pBufferSurface, pBufferSurface, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
|
||||
|
||||
glViewport(0, 0, kWidth, kHeight);
|
||||
glClearColor(1.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glFinish();
|
||||
ASSERT_GL_NO_ERROR() << "glFinish failed";
|
||||
|
||||
OSWindow *osWindow = OSWindow::New();
|
||||
osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
|
||||
EGLSurface windowSurface = EGL_NO_SURFACE;
|
||||
EGLBoolean createWinSurfaceResult = createWindowSurface(
|
||||
isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
|
||||
EXPECT_TRUE(createWinSurfaceResult);
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
|
||||
glViewport(0, 0, kWidth, kHeight);
|
||||
|
||||
if (IsGLExtensionEnabled("GL_EXT_protected_textures"))
|
||||
{
|
||||
GLuint texture = 0;
|
||||
EXPECT_TRUE(createTextureFromPbuffer(pBufferSurface, &texture));
|
||||
EXPECT_TRUE(renderTexture(texture));
|
||||
|
||||
eglSwapBuffers(mDisplay, windowSurface);
|
||||
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
|
||||
checkSwapBuffersResult("RED", isProtectedContext, isProtectedTexture);
|
||||
|
||||
eglReleaseTexImage(mDisplay, pBufferSurface, EGL_BACK_BUFFER);
|
||||
glDeleteTextures(1, &texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Skipping tests, GL_EXT_protected_textures not supported" << std::endl;
|
||||
}
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
|
||||
|
||||
eglDestroySurface(mDisplay, windowSurface);
|
||||
windowSurface = EGL_NO_SURFACE;
|
||||
osWindow->destroy();
|
||||
OSWindow::Delete(&osWindow);
|
||||
|
||||
eglDestroySurface(mDisplay, pBufferSurface);
|
||||
pBufferSurface = EGL_NO_SURFACE;
|
||||
|
||||
eglDestroyContext(mDisplay, context);
|
||||
context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
// Unprotected context with unprotected texture from BindTex of PBufferSurface
|
||||
TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTextureFromPBuffer)
|
||||
{
|
||||
textureFromPbufferTest(false, false);
|
||||
}
|
||||
|
||||
// Protected context with protected texture from BindTex of PBufferSurface
|
||||
TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTextureFromPbuffer)
|
||||
{
|
||||
textureFromPbufferTest(true, true);
|
||||
}
|
||||
|
||||
void EGLProtectedContentTest::textureFromAndroidNativeBufferTest(bool isProtectedContext,
|
||||
bool isProtectedTexture)
|
||||
{
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_EXT_protected_content"));
|
||||
ANGLE_SKIP_TEST_IF(
|
||||
!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_get_native_client_buffer"));
|
||||
ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANDROID_image_native_buffer"));
|
||||
|
||||
bool isProtectedSurface = isProtectedTexture;
|
||||
|
||||
EGLConfig config = EGL_NO_CONFIG_KHR;
|
||||
EXPECT_TRUE(chooseConfig(&config));
|
||||
ANGLE_SKIP_TEST_IF(config == EGL_NO_CONFIG_KHR);
|
||||
|
||||
EGLContext context = EGL_NO_CONTEXT;
|
||||
EXPECT_TRUE(createContext(isProtectedContext, config, &context));
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateContext failed.";
|
||||
|
||||
OSWindow *osWindow = OSWindow::New();
|
||||
osWindow->initialize("ProtectedContentTest", kWidth, kHeight);
|
||||
EGLSurface windowSurface = EGL_NO_SURFACE;
|
||||
EGLBoolean createWinSurfaceResult = createWindowSurface(
|
||||
isProtectedSurface, config, osWindow->getNativeWindow(), &windowSurface);
|
||||
EXPECT_TRUE(createWinSurfaceResult);
|
||||
ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, windowSurface, windowSurface, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent failed.";
|
||||
glViewport(0, 0, kWidth, kHeight);
|
||||
|
||||
if (IsGLExtensionEnabled("GL_EXT_protected_textures"))
|
||||
{
|
||||
EGLClientBuffer clientBuffer = nullptr;
|
||||
EXPECT_TRUE(createAndroidClientBuffer(isProtectedTexture, false, true, &clientBuffer));
|
||||
|
||||
EGLImage image = EGL_NO_IMAGE;
|
||||
EXPECT_TRUE(createImage(isProtectedTexture, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
|
||||
clientBuffer, &image));
|
||||
|
||||
GLuint texture = 0;
|
||||
if (isProtectedTexture && !isProtectedContext)
|
||||
{
|
||||
std::cout << "Can't create protected Texture for Unprotected Context, Skipping"
|
||||
<< std::endl;
|
||||
ASSERT_FALSE(createTextureFromImage(image, &texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
EXPECT_TRUE(createTextureFromImage(image, &texture));
|
||||
EXPECT_TRUE(fillTexture(texture, GLColor::red));
|
||||
EXPECT_TRUE(renderTexture(texture));
|
||||
|
||||
eglSwapBuffers(mDisplay, windowSurface);
|
||||
ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
|
||||
checkSwapBuffersResult("RED", isProtectedContext, isProtectedTexture);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTextures(1, &texture);
|
||||
|
||||
eglDestroyImage(mDisplay, image);
|
||||
image = EGL_NO_IMAGE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Skipping tests, GL_EXT_protected_textures not supported" << std::endl;
|
||||
}
|
||||
|
||||
EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context));
|
||||
ASSERT_EGL_SUCCESS() << "eglMakeCurrent - uncurrent failed.";
|
||||
|
||||
eglDestroySurface(mDisplay, windowSurface);
|
||||
windowSurface = EGL_NO_SURFACE;
|
||||
osWindow->destroy();
|
||||
OSWindow::Delete(&osWindow);
|
||||
|
||||
eglDestroyContext(mDisplay, context);
|
||||
context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
// Unprotected context with unprotected texture from EGL image from Android native buffer
|
||||
TEST_P(EGLProtectedContentTest, UnprotectedContextWithUnprotectedTextureFromAndroidNativeBuffer)
|
||||
{
|
||||
textureFromAndroidNativeBufferTest(false, false);
|
||||
}
|
||||
|
||||
// Protected context with protected texture from EGL image from Android native buffer
|
||||
TEST_P(EGLProtectedContentTest, ProtectedContextWithProtectedTextureFromAndroidNativeBuffer)
|
||||
{
|
||||
textureFromAndroidNativeBufferTest(true, true);
|
||||
}
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(EGLProtectedContentTest,
|
||||
|
|
Загрузка…
Ссылка в новой задаче