Commit b66a9097 by Geoff Lang Committed by Commit Bot

Add support for OES_EGL_image_external and OES_EGL_image_external_essl3.

BUG=angleproject:1372 Change-Id: I8489e7fd0ab409b0775041ad5e9fbf0aab53886d Reviewed-on: https://chromium-review.googlesource.com/344734Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent a0d3aa41
......@@ -48,7 +48,7 @@ typedef unsigned int GLenum;
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 145
#define ANGLE_SH_VERSION 146
typedef enum {
SH_GLES2_SPEC = 0x8B40,
......@@ -255,6 +255,7 @@ typedef struct
// Set to 1 to enable the extension, else 0.
int OES_standard_derivatives;
int OES_EGL_image_external;
int OES_EGL_image_external_essl3;
int NV_EGL_stream_consumer_external;
int ARB_texture_rectangle;
int EXT_blend_func_extended;
......
......@@ -480,6 +480,8 @@ void TCompiler::initSamplerDefaultPrecision(TBasicType samplerType)
void TCompiler::setResourceString()
{
std::ostringstream strstream;
// clang-format off
strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
<< ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
<< ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
......@@ -490,6 +492,8 @@ void TCompiler::setResourceString()
<< ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
<< ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
<< ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
<< ":OES_EGL_image_external_essl3:" << compileResources.OES_EGL_image_external_essl3
<< ":NV_EGL_stream_consumer_external:" << compileResources.NV_EGL_stream_consumer_external
<< ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
<< ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
<< ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
......@@ -509,6 +513,7 @@ void TCompiler::setResourceString()
<< ":MaxDualSourceDrawBuffers:" << compileResources.MaxDualSourceDrawBuffers
<< ":NV_draw_buffers:" << compileResources.NV_draw_buffers
<< ":WEBGL_debug_shader_precision:" << compileResources.WEBGL_debug_shader_precision;
// clang-format on
builtInResourcesString = strstream.str();
}
......
......@@ -315,6 +315,17 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsamplerCube, float3, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureLod", gsampler2DArray, float3, float1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float4);
}
if (type == GL_FRAGMENT_SHADER)
{
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texture", gsampler2D, float2, float1);
......@@ -324,6 +335,18 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float3, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler2D, float4, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "textureProj", gsampler3D, float4, float1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texture", samplerExternalOES, float2,
float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float3, float1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "textureProj", samplerExternalOES,
float4, float1);
}
}
const TType *sampler2DShadow = TCache::getType(EbtSampler2DShadow);
......@@ -351,6 +374,13 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerCubeShadow, int1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int3, "textureSize", sampler2DArrayShadow, int1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, int2, "textureSize", samplerExternalOES, int1);
}
if (type == GL_FRAGMENT_SHADER)
{
symbolTable.insertBuiltIn(ESSL3_BUILTINS, EOpDFdx, genType, "dFdx", genType);
......@@ -403,6 +433,14 @@ void InsertBuiltInFunctions(sh::GLenum type, ShShaderSpec spec, const ShBuiltInR
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler3D, int3, int1);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetch", gsampler2DArray, int3, int1);
if (resources.OES_EGL_image_external_essl3)
{
const TType *samplerExternalOES = TCache::getType(EbtSamplerExternalOES);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, float4, "texelFetch", samplerExternalOES, int2,
int1);
}
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2D, int2, int1, int2);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler3D, int3, int1, int3);
symbolTable.insertBuiltIn(ESSL3_BUILTINS, gvec4, "texelFetchOffset", gsampler2DArray, int3, int1, int2);
......@@ -594,6 +632,8 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_OES_standard_derivatives"] = EBhUndefined;
if (resources.OES_EGL_image_external)
extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
if (resources.OES_EGL_image_external_essl3)
extBehavior["GL_OES_EGL_image_external_essl3"] = EBhUndefined;
if (resources.NV_EGL_stream_consumer_external)
extBehavior["GL_NV_EGL_stream_consumer_external"] = EBhUndefined;
if (resources.ARB_texture_rectangle)
......
......@@ -148,6 +148,8 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
// Extensions.
resources->OES_standard_derivatives = 0;
resources->OES_EGL_image_external = 0;
resources->OES_EGL_image_external_essl3 = 0;
resources->NV_EGL_stream_consumer_external = 0;
resources->ARB_texture_rectangle = 0;
resources->EXT_blend_func_extended = 0;
resources->EXT_draw_buffers = 0;
......
......@@ -201,6 +201,7 @@ int GetHLSLCoordCount(const TextureFunctionHLSL::TextureFunction &textureFunctio
switch (textureFunction.sampler)
{
case EbtSampler2D:
case EbtSamplerExternalOES:
hlslCoords = 2;
break;
case EbtSamplerCube:
......@@ -275,6 +276,7 @@ void OutputTextureFunctionArgumentList(TInfoSinkBase &out,
switch (textureFunction.sampler)
{
case EbtSampler2D:
case EbtSamplerExternalOES:
out << "sampler2D s";
break;
case EbtSamplerCube:
......@@ -790,6 +792,7 @@ void OutputTextureSampleFunctionReturnStatement(
switch (textureFunction.sampler)
{
case EbtSampler2D:
case EbtSamplerExternalOES:
out << "tex2D";
break;
case EbtSamplerCube:
......
......@@ -50,8 +50,8 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const ContextState &data)
mResources.OES_standard_derivatives = extensions.standardDerivatives;
mResources.EXT_draw_buffers = extensions.drawBuffers;
mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD;
// TODO: disabled until the extension is actually supported.
mResources.OES_EGL_image_external = 0;
mResources.OES_EGL_image_external = extensions.eglImageExternal;
mResources.OES_EGL_image_external_essl3 = extensions.eglImageExternalEssl3;
mResources.NV_EGL_stream_consumer_external = extensions.eglStreamConsumerExternal;
// TODO: use shader precision caps to determine if high precision is supported?
mResources.FragmentPrecisionHigh = 1;
......
......@@ -2089,6 +2089,7 @@ void Context::initCaps(GLuint clientVersion)
{
// Disable ES3+ extensions
mExtensions.colorBufferFloat = false;
mExtensions.eglImageExternalEssl3 = false;
}
if (clientVersion > 2)
......
......@@ -61,7 +61,7 @@ TextureState::TextureState(GLenum target)
swizzleGreen(GL_GREEN),
swizzleBlue(GL_BLUE),
swizzleAlpha(GL_ALPHA),
samplerState(),
samplerState(SamplerState::CreateDefaultForTarget(target)),
baseLevel(0),
maxLevel(1000),
immutableFormat(false),
......@@ -755,7 +755,7 @@ void Texture::releaseTexImageInternal()
Error Texture::setEGLImageTarget(GLenum target, egl::Image *imageTarget)
{
ASSERT(target == mState.target);
ASSERT(target == GL_TEXTURE_2D);
ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES);
// Release from previous calls to eglBindTexImage, to avoid calling the Impl after
releaseTexImageInternal();
......@@ -847,6 +847,27 @@ bool Texture::computeSamplerCompleteness(const SamplerState &samplerState,
}
}
// From GL_OES_EGL_image_external_essl3: If state is present in a sampler object bound to a
// texture unit that would have been rejected by a call to TexParameter* for the texture bound
// to that unit, the behavior of the implementation is as if the texture were incomplete. For
// example, if TEXTURE_WRAP_S or TEXTURE_WRAP_T is set to anything but CLAMP_TO_EDGE on the
// sampler object bound to a texture unit and the texture bound to that unit is an external
// texture, the texture will be considered incomplete.
// Sampler object state which does not affect sampling for the type of texture bound to a
// texture unit, such as TEXTURE_WRAP_R for an external texture, does not affect completeness.
if (mState.target == GL_TEXTURE_EXTERNAL_OES)
{
if (samplerState.wrapS != GL_CLAMP_TO_EDGE || samplerState.wrapT != GL_CLAMP_TO_EDGE)
{
return false;
}
if (samplerState.minFilter != GL_LINEAR && samplerState.minFilter != GL_NEAREST)
{
return false;
}
}
// OpenGLES 3.0.2 spec section 3.8.13 states that a texture is not mipmap complete if:
// The internalformat specified for the texture arrays is a sized internal depth or
// depth and stencil format (see table 3.13), the value of TEXTURE_COMPARE_-
......
......@@ -53,6 +53,23 @@ SamplerState::SamplerState()
{
}
// static
SamplerState SamplerState::CreateDefaultForTarget(GLenum target)
{
SamplerState state;
// According to OES_EGL_image_external: For external textures, the default min filter is
// GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE.
if (target == GL_TEXTURE_EXTERNAL_OES)
{
state.minFilter = GL_LINEAR;
state.wrapS = GL_CLAMP_TO_EDGE;
state.wrapT = GL_CLAMP_TO_EDGE;
}
return state;
}
static void MinMax(int a, int b, int *minimum, int *maximum)
{
if (a < b)
......
......@@ -194,6 +194,7 @@ struct DepthStencilState
struct SamplerState
{
SamplerState();
static SamplerState CreateDefaultForTarget(GLenum target);
GLenum minFilter;
GLenum magFilter;
......
......@@ -3178,21 +3178,17 @@ void TextureD3D_2DArray::markAllImagesDirty()
TextureD3D_External::TextureD3D_External(const gl::TextureState &state, RendererD3D *renderer)
: TextureD3D(state, renderer)
{
mImage = renderer->createImage();
}
TextureD3D_External::~TextureD3D_External()
{
SafeDelete(mImage);
SafeDelete(mTexStorage);
}
ImageD3D *TextureD3D_External::getImage(const gl::ImageIndex &index) const
{
// External images only have one mipmap level
ASSERT(index.type == GL_TEXTURE_EXTERNAL_OES);
ASSERT(index.mipIndex == 0);
return mImage;
UNREACHABLE();
return nullptr;
}
GLsizei TextureD3D_External::getLayerCount(int level) const
......@@ -3200,29 +3196,6 @@ GLsizei TextureD3D_External::getLayerCount(int level) const
return 1;
}
GLsizei TextureD3D_External::getWidth(GLint level) const
{
ASSERT(level == 0);
return mImage->getWidth();
}
GLsizei TextureD3D_External::getHeight(GLint level) const
{
ASSERT(level == 0);
return mImage->getHeight();
}
GLenum TextureD3D_External::getInternalFormat(GLint level) const
{
ASSERT(level == 0);
return mImage->getInternalFormat();
}
bool TextureD3D_External::isDepth(GLint level) const
{
return false;
}
gl::Error TextureD3D_External::setImage(GLenum target,
size_t imageLevel,
GLenum internalFormat,
......@@ -3308,15 +3281,11 @@ gl::Error TextureD3D_External::setImageExternal(GLenum target,
{
ASSERT(target == GL_TEXTURE_EXTERNAL_OES);
// If the strean is null, the external image is unbound and we release the storage
if (stream == nullptr)
{
SafeDelete(mTexStorage);
mTexStorage = nullptr;
}
else
SafeDelete(mTexStorage);
// If the stream is null, the external image is unbound and we release the storage
if (stream != nullptr)
{
SafeDelete(mTexStorage);
mTexStorage = mRenderer->createTextureStorageExternal(stream, desc);
}
......@@ -3335,8 +3304,12 @@ void TextureD3D_External::releaseTexImage()
gl::Error TextureD3D_External::setEGLImageTarget(GLenum target, egl::Image *image)
{
UNREACHABLE();
return gl::Error(GL_INVALID_OPERATION);
EGLImageD3D *eglImaged3d = GetImplAs<EGLImageD3D>(image);
SafeDelete(mTexStorage);
mTexStorage = mRenderer->createTextureStorageEGLImage(eglImaged3d);
return gl::NoError();
}
void TextureD3D_External::initMipmapsImages()
......@@ -3350,19 +3323,9 @@ gl::Error TextureD3D_External::getRenderTarget(const gl::ImageIndex &index, Rend
return gl::Error(GL_INVALID_OPERATION);
}
bool TextureD3D_External::isValidLevel(int level) const
{
return (level == 0);
}
bool TextureD3D_External::isLevelComplete(int level) const
{
return (level == 0) ? (mTexStorage != nullptr) : false;
}
bool TextureD3D_External::isImageComplete(const gl::ImageIndex &index) const
{
return isLevelComplete(index.mipIndex);
return (index.mipIndex == 0) ? (mTexStorage != nullptr) : false;
}
gl::Error TextureD3D_External::initializeStorage(bool renderTarget)
......@@ -3393,20 +3356,6 @@ gl::Error TextureD3D_External::updateStorage()
return gl::Error(GL_NO_ERROR);
}
gl::Error TextureD3D_External::updateStorageLevel(int level)
{
UNREACHABLE();
return gl::Error(GL_NO_ERROR);
}
void TextureD3D_External::redefineImage(size_t level,
GLenum internalformat,
const gl::Extents &size,
bool forceRelease)
{
UNREACHABLE();
}
gl::ImageIndexIterator TextureD3D_External::imageIterator() const
{
return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
......
......@@ -413,11 +413,6 @@ class TextureD3D_External : public TextureD3D
ImageD3D *getImage(const gl::ImageIndex &index) const override;
GLsizei getLayerCount(int level) const override;
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
bool isDepth(GLint level) const;
gl::Error setImage(GLenum target,
size_t level,
GLenum internalFormat,
......@@ -492,18 +487,7 @@ class TextureD3D_External : public TextureD3D
gl::Error updateStorage() override;
void initMipmapsImages() override;
bool isValidLevel(int level) const;
bool isLevelComplete(int level) const;
bool isImageComplete(const gl::ImageIndex &index) const override;
gl::Error updateStorageLevel(int level);
void redefineImage(size_t level,
GLenum internalformat,
const gl::Extents &size,
bool forceRelease);
ImageD3D *mImage;
};
}
......
......@@ -1231,6 +1231,8 @@ void GenerateCaps(ID3D11Device *device, ID3D11DeviceContext *deviceContext, cons
extensions->fboRenderMipmap = false;
extensions->debugMarker = true;
extensions->eglImage = true;
extensions->eglImageExternal = true;
extensions->eglImageExternalEssl3 = true;
extensions->eglStreamConsumerExternal = true;
extensions->unpackSubimage = true;
extensions->packSubimage = true;
......
......@@ -69,6 +69,8 @@ TextureImpl *Context9::createTexture(const gl::TextureState &state)
return new TextureD3D_2D(state, mRenderer);
case GL_TEXTURE_CUBE_MAP:
return new TextureD3D_Cube(state, mRenderer);
case GL_TEXTURE_EXTERNAL_OES:
return new TextureD3D_External(state, mRenderer);
default:
UNREACHABLE();
}
......
......@@ -1657,6 +1657,7 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D,
{
case GL_SAMPLER_2D:
case GL_SAMPLER_CUBE:
case GL_SAMPLER_EXTERNAL_OES:
break;
case GL_BOOL:
case GL_BOOL_VEC2:
......
......@@ -590,6 +590,7 @@ void GenerateCaps(IDirect3D9 *d3d9,
extensions->colorBufferFloat = false;
extensions->debugMarker = true;
extensions->eglImage = true;
extensions->eglImageExternal = true;
extensions->unpackSubimage = true;
extensions->packSubimage = true;
extensions->vertexArrayObject = true;
......
......@@ -857,13 +857,18 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pnam
case GL_TEXTURE_COMPARE_FUNC:
case GL_TEXTURE_MIN_LOD:
case GL_TEXTURE_MAX_LOD:
// ES3 texture paramters are not supported on external textures as the extension is
// written against ES2.
if (context->getClientVersion() < 3 || target == GL_TEXTURE_EXTERNAL_OES)
if (context->getClientVersion() < 3)
{
context->handleError(Error(GL_INVALID_ENUM));
return false;
}
if (target == GL_TEXTURE_EXTERNAL_OES && !context->getExtensions().eglImageExternalEssl3)
{
context->handleError(Error(GL_INVALID_ENUM,
"ES3 texture parameters are not available without "
"GL_OES_EGL_image_external_essl3."));
return false;
}
break;
default: break;
......@@ -1014,16 +1019,20 @@ bool ValidateTexParamParameters(gl::Context *context, GLenum target, GLenum pnam
break;
case GL_TEXTURE_BASE_LEVEL:
case GL_TEXTURE_MAX_LEVEL:
if (target == GL_TEXTURE_EXTERNAL_OES)
if (param < 0)
{
context->handleError(Error(GL_INVALID_VALUE));
return false;
}
if (target == GL_TEXTURE_EXTERNAL_OES && param != 0)
{
// This is not specified, but in line with the spirit of OES_EGL_image_external spec,
// which generally forbids setting mipmap related parameters on external textures.
context->handleError(
Error(GL_INVALID_OPERATION,
"Setting the base level or max level of external textures not supported"));
Error(GL_INVALID_OPERATION, "Base level must be 0 for external textures."));
return false;
}
return true;
case GL_TEXTURE_MAX_LEVEL:
if (param < 0)
{
context->handleError(Error(GL_INVALID_VALUE));
......@@ -2398,6 +2407,20 @@ bool ValidateEGLImageTargetTexture2DOES(Context *context,
switch (target)
{
case GL_TEXTURE_2D:
if (!context->getExtensions().eglImage)
{
context->handleError(Error(
GL_INVALID_ENUM, "GL_TEXTURE_2D texture target requires GL_OES_EGL_image."));
}
break;
case GL_TEXTURE_EXTERNAL_OES:
if (!context->getExtensions().eglImageExternal)
{
context->handleError(Error(
GL_INVALID_ENUM,
"GL_TEXTURE_EXTERNAL_OES texture target requires GL_OES_EGL_image_external."));
}
break;
default:
......
......@@ -1997,7 +1997,8 @@ bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
}
break;
case GL_TEXTURE_EXTERNAL_OES:
if (!context->getExtensions().eglStreamConsumerExternal)
if (!context->getExtensions().eglImageExternal &&
!context->getExtensions().eglStreamConsumerExternal)
{
context->handleError(
Error(GL_INVALID_ENUM, "External texture extension not enabled"));
......
......@@ -2279,7 +2279,7 @@ void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
Context *context = GetValidGlobalContext();
if (context)
{
if (!ValidTextureTarget(context, target))
if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
{
context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
return;
......@@ -2434,7 +2434,7 @@ void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
Context *context = GetValidGlobalContext();
if (context)
{
if (!ValidTextureTarget(context, target))
if (!ValidTextureTarget(context, target) && !ValidTextureExternalTarget(context, target))
{
context->handleError(Error(GL_INVALID_ENUM, "Invalid texture target"));
return;
......
......@@ -358,37 +358,79 @@ TEST_P(EGLStreamTest, StreamProducerTextureNV12End2End)
{
EGLWindow *window = getEGLWindow();
EGLDisplay display = window->getDisplay();
const char *extensionsString = eglQueryString(display, EGL_EXTENSIONS);
if (strstr(extensionsString, "EGL_ANGLE_stream_producer_d3d_texture_nv12") == nullptr)
if (!eglDisplayExtensionEnabled(display, "EGL_ANGLE_stream_producer_d3d_texture_nv12"))
{
std::cout << "Stream producer d3d nv12 texture not supported" << std::endl;
return;
}
// Shader setup
const std::string yuvVS =
"attribute highp vec4 position; varying vec2 texcoord; void main(void)\n"
"{\n"
" gl_Position = position;\n"
" texcoord = (position.xy * 0.5) + 0.5;\n"
" texcoord.y = 1.0 - texcoord.y;\n"
"}\n";
bool useESSL3Shaders =
getClientVersion() >= 3 && extensionEnabled("GL_OES_EGL_image_external_essl3");
// yuv to rgb conversion shader using Microsoft's given conversion formulas
const std::string yuvPS =
"#extension GL_NV_EGL_stream_consumer_external : require\n"
"precision highp float; varying vec2 texcoord;\n"
"uniform samplerExternalOES y; uniform samplerExternalOES uv\n;"
"void main(void)\n"
"{\n"
" float c = texture2D(y, texcoord).r - (16.0 / 256.0);\n"
" float d = texture2D(uv, texcoord).r - 0.5;\n"
" float e = texture2D(uv, texcoord).g - 0.5;\n"
" float r = 1.164383 * c + 1.596027 * e;\n"
" float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
" float b = 1.164383 * c + 2.017232 * d;\n"
" gl_FragColor = vec4(r, g, b, 1.0);\n"
"}\n";
std::string yuvVS, yuvPS;
if (useESSL3Shaders)
{
yuvVS =
"#version 300 es\n"
"in highp vec4 position;\n"
"out vec2 texcoord;\n"
"void main(void)\n"
"{\n"
" gl_Position = position;\n"
" texcoord = (position.xy * 0.5) + 0.5;\n"
" texcoord.y = 1.0 - texcoord.y;\n"
"}\n";
yuvPS =
"#version 300 es\n"
"#extension GL_OES_EGL_image_external_essl3 : require\n"
"#extension GL_NV_EGL_stream_consumer_external : require\n"
"precision highp float;\n"
"in vec2 texcoord;\n"
"out vec4 color;\n"
"uniform samplerExternalOES y;\n"
"uniform samplerExternalOES uv\n;"
"void main(void)\n"
"{\n"
" float c = texture(y, texcoord).r - (16.0 / 256.0);\n"
" float d = texture(uv, texcoord).r - 0.5;\n"
" float e = texture(uv, texcoord).g - 0.5;\n"
" float r = 1.164383 * c + 1.596027 * e;\n"
" float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
" float b = 1.164383 * c + 2.017232 * d;\n"
" color = vec4(r, g, b, 1.0);\n"
"}\n";
}
else
{
yuvVS =
"attribute highp vec4 position;\n"
"varying vec2 texcoord;\n"
"void main(void)\n"
"{\n"
" gl_Position = position;\n"
" texcoord = (position.xy * 0.5) + 0.5;\n"
" texcoord.y = 1.0 - texcoord.y;\n"
"}\n";
yuvPS =
"#extension GL_NV_EGL_stream_consumer_external : require\n"
"precision highp float;\n"
"varying vec2 texcoord;\n"
"uniform samplerExternalOES y;\n"
"uniform samplerExternalOES uv\n;"
"void main(void)\n"
"{\n"
" float c = texture2D(y, texcoord).r - (16.0 / 256.0);\n"
" float d = texture2D(uv, texcoord).r - 0.5;\n"
" float e = texture2D(uv, texcoord).g - 0.5;\n"
" float r = 1.164383 * c + 1.596027 * e;\n"
" float g = 1.164383 * c - 0.391762 * d - 0.812968 * e;\n"
" float b = 1.164383 * c + 2.017232 * d;\n"
" gl_FragColor = vec4(r, g, b, 1.0);\n"
"}\n";
}
GLuint program = CompileProgram(yuvVS, yuvPS);
ASSERT_NE(0u, program);
GLuint yUniform = glGetUniformLocation(program, "y");
......
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