blob: a38aa299a541053f307d4a8824c909bc847e34ef [file] [log] [blame]
//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
using namespace angle;
namespace
{
class WEBGLVideoTextureTest : public ANGLETest
{
protected:
WEBGLVideoTextureTest()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
};
class WEBGLVideoTextureES300Test : public ANGLETest
{
protected:
WEBGLVideoTextureES300Test()
{
setWindowWidth(128);
setWindowHeight(128);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
}
};
// Test to verify samplerVideoWEBGL works fine when extension is enabled.
TEST_P(WEBGLVideoTextureTest, VerifySamplerVideoWEBGL)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
constexpr char kVS[] = R"(
attribute vec2 position;
varying mediump vec2 texCoord;
void main()
{
gl_Position = vec4(position, 0, 1);
texCoord = position * 0.5 + vec2(0.5);
})";
constexpr char kFS[] = R"(
#extension GL_WEBGL_video_texture : require
precision mediump float;
varying mediump vec2 texCoord;
uniform mediump samplerVideoWEBGL s;
void main()
{
gl_FragColor = textureVideoWEBGL(s, texCoord);
})";
ANGLE_GL_PROGRAM(program, kVS, kFS);
// Initialize basic red texture.
const std::vector<GLColor> redColors(4, GLColor::red);
GLTexture texture;
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, texture);
glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
redColors.data());
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
drawQuad(program, "position", 0.0f);
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
ASSERT_GL_NO_ERROR();
}
// Test to verify samplerVideoWEBGL works fine as parameter of user defined function
// when extension is enabled.
TEST_P(WEBGLVideoTextureTest, VerifySamplerVideoWEBGLAsParameter)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
constexpr char kVS[] = R"(
attribute vec2 position;
varying mediump vec2 texCoord;
void main()
{
gl_Position = vec4(position, 0, 1);
texCoord = position * 0.5 + vec2(0.5);
})";
constexpr char kFS[] = R"(
#extension GL_WEBGL_video_texture : require
precision mediump float;
varying mediump vec2 texCoord;
uniform mediump samplerVideoWEBGL s;
vec4 wrapTextureVideoWEBGL(samplerVideoWEBGL sampler, vec2 coord)
{
return textureVideoWEBGL(sampler, coord);
}
void main()
{
gl_FragColor = wrapTextureVideoWEBGL(s, texCoord);
})";
ANGLE_GL_PROGRAM(program, kVS, kFS);
// Initialize basic red texture.
const std::vector<GLColor> redColors(4, GLColor::red);
GLTexture texture;
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, texture);
glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
redColors.data());
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
drawQuad(program, "position", 0.0f);
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
ASSERT_GL_NO_ERROR();
}
// Test to ensure ANGLE state manager knows the change when binding VideoImage
// and can handle it correctly based on the program.
TEST_P(WEBGLVideoTextureTest, VerifyStateManagerKnowsBindingVideoImage)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
constexpr char kVS[] = R"(
attribute vec2 position;
varying mediump vec2 texCoord;
void main()
{
gl_Position = vec4(position, 0, 1);
texCoord = position * 0.5 + vec2(0.5);
})";
constexpr char kFS2D[] = R"(
precision mediump float;
varying mediump vec2 texCoord;
uniform mediump sampler2D s;
void main()
{
gl_FragColor = texture2D(s, texCoord);
})";
constexpr char kFSVideoImage[] = R"(
#extension GL_WEBGL_video_texture : require
precision mediump float;
varying mediump vec2 texCoord;
uniform mediump samplerVideoWEBGL s;
void main()
{
gl_FragColor = textureVideoWEBGL(s, texCoord);
})";
ANGLE_GL_PROGRAM(program2D, kVS, kFS2D);
ANGLE_GL_PROGRAM(programVideoImage, kVS, kFSVideoImage);
// Initialize basic red texture.
const std::vector<GLColor> redColors(4, GLColor::red);
const std::vector<GLColor> greenColors(4, GLColor::green);
GLTexture texture2D;
GLTexture textureVideoImage;
glBindTexture(GL_TEXTURE_2D, texture2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, redColors.data());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
// This should unbind the native TEXTURE_2D
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, textureVideoImage);
glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
greenColors.data());
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
// ANGLE will check state change and apply changes through state manager. If state manager
// is aware of the unbind, it will bind the correct texture back in native and the draw should
// work fine.
drawQuad(program2D, "position", 0.0f);
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
drawQuad(programVideoImage, "position", 0.0f);
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
drawQuad(program2D, "position", 0.0f);
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
glBindTexture(GL_TEXTURE_2D, 0);
ASSERT_GL_NO_ERROR();
}
// Test to verify samplerVideoWEBGL works fine in ES300 when extension is enabled.
TEST_P(WEBGLVideoTextureES300Test, VerifySamplerVideoWEBGLInES300)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_WEBGL_video_texture"));
constexpr char kVS[] = R"(#version 300 es
in vec2 position;
out mediump vec2 texCoord;
void main()
{
gl_Position = vec4(position, 0, 1);
texCoord = position * 0.5 + vec2(0.5);
})";
constexpr char kFS[] = R"(#version 300 es
#extension GL_WEBGL_video_texture : require
precision mediump float;
in mediump vec2 texCoord;
uniform mediump samplerVideoWEBGL s;
out vec4 my_FragColor;
void main()
{
my_FragColor = texture(s, texCoord);
})";
ANGLE_GL_PROGRAM(program, kVS, kFS);
// Initialize basic red texture.
const std::vector<GLColor> redColors(4, GLColor::red);
GLTexture texture;
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, texture);
glTexImage2D(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
redColors.data());
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_VIDEO_IMAGE_WEBGL, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
ASSERT_GL_NO_ERROR();
drawQuad(program, "position", 0.0f);
EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
glBindTexture(GL_TEXTURE_VIDEO_IMAGE_WEBGL, 0);
ASSERT_GL_NO_ERROR();
}
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(WEBGLVideoTextureTest);
ANGLE_INSTANTIATE_TEST_ES3(WEBGLVideoTextureES300Test);
} // namespace