summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer
diff options
context:
space:
mode:
authorvangelis@chromium.org <vangelis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-06 17:26:17 +0000
committervangelis@chromium.org <vangelis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-06 17:26:17 +0000
commit97dc7cbe1b802facd4ccf92c6f7da78bd5a8ce51 (patch)
tree93e396f7cef6348bbebcd3c83cbdf7eb023d0d3f /gpu/command_buffer
parentfa8e6464f65a0f0304ea199d04ca531dbab79f99 (diff)
downloadchromium_src-97dc7cbe1b802facd4ccf92c6f7da78bd5a8ce51.zip
chromium_src-97dc7cbe1b802facd4ccf92c6f7da78bd5a8ce51.tar.gz
chromium_src-97dc7cbe1b802facd4ccf92c6f7da78bd5a8ce51.tar.bz2
Adds support for the GL_ANGLE_texture_usage and GL_EXT_texture_storage
extensions to the command buffer and the WebGraphicsContext3D APIs. BUG=106142 TEST=unittests Review URL: http://codereview.chromium.org/8772033 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113223 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu/command_buffer')
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py28
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h6
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h19
-rw-r--r--gpu/command_buffer/common/gl_mock.h4
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h55
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h21
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h1
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_autogen.h2
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h50
-rw-r--r--gpu/command_buffer/service/feature_info.cc30
-rw-r--r--gpu/command_buffer/service/feature_info_unittest.cc6
-rw-r--r--gpu/command_buffer/service/gl_utils.h21
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc160
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h33
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc11
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h3
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_autogen.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h21
-rw-r--r--gpu/command_buffer/service/texture_manager.cc27
-rw-r--r--gpu/command_buffer/service/texture_manager.h31
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc35
23 files changed, 548 insertions, 27 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 16fc4d2..c3ce764 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -201,6 +201,7 @@ GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLintVer
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
GL_APICALL void GL_APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenumBlitFilter filter);
GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenumRenderBufferTarget target, GLsizei samples, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenumTextureTarget target, GLsizei levels, GLintTextureInternalFormatStorage internalFormat, GLsizei width, GLsizei height);
// Non-GL commands.
GL_APICALL void GL_APIENTRY glSwapBuffers (void);
GL_APICALL GLuint GL_APIENTRY glGetMaxValueInBufferCHROMIUM (GLidBuffer buffer_id, GLsizei count, GLenumGetMaxIndexType type, GLuint offset);
@@ -436,6 +437,7 @@ _CMD_ID_TABLE = {
'GetTranslatedShaderSourceANGLE': 456,
'PostSubBufferCHROMIUM': 457,
'TexImageIOSurface2DCHROMIUM': 458,
+ 'TexStorage2DEXT': 459,
}
# This is a list of enum names and their valid values. It is used to map
@@ -898,6 +900,13 @@ _ENUM_LISTS = {
'GL_LINEAR',
],
},
+ 'TextureUsage': {
+ 'type': 'GLenum',
+ 'valid': [
+ 'GL_NONE',
+ 'GL_FRAMEBUFFER_ATTACHMENT_ANGLE',
+ ],
+ },
'VertexAttribute': {
'type': 'GLenum',
'valid': [
@@ -1036,6 +1045,19 @@ _ENUM_LISTS = {
'GL_BGR',
],
},
+ 'TextureInternalFormatStorage': {
+ 'type': 'GLenum',
+ 'valid': [
+ 'GL_RGB565',
+ 'GL_RGBA4',
+ 'GL_RGB5_A1',
+ 'GL_ALPHA8_EXT',
+ 'GL_LUMINANCE8_EXT',
+ 'GL_LUMINANCE8_ALPHA8_EXT',
+ 'GL_RGB8_OES',
+ 'GL_RGBA8_OES',
+ ],
+ },
'VertexAttribType': {
'type': 'GLenum',
'valid': [
@@ -1801,6 +1823,12 @@ _FUNCTION_INFO = {
'extension': True,
'chromium': True,
},
+ 'TexStorage2DEXT': {
+ 'unit_test': False,
+ 'extension': True,
+ 'decoder_func': 'DoTexStorage2DEXT',
+ },
+
}
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index d7fde69..76dc082 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -514,6 +514,12 @@ void GLES2RenderbufferStorageMultisampleEXT(
gles2::GetGLContext()->RenderbufferStorageMultisampleEXT(
target, samples, internalformat, width, height);
}
+void GLES2TexStorage2DEXT(
+ GLenum target, GLsizei levels, GLint internalFormat, GLsizei width,
+ GLsizei height) {
+ gles2::GetGLContext()->TexStorage2DEXT(
+ target, levels, internalFormat, width, height);
+}
void GLES2SwapBuffers() {
gles2::GetGLContext()->SwapBuffers();
}
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 8e1ec4e..c3e5497 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1151,6 +1151,13 @@
c.Init(target, samples, internalformat, width, height);
}
+ void TexStorage2DEXT(
+ GLenum target, GLsizei levels, GLint internalFormat, GLsizei width,
+ GLsizei height) {
+ gles2::TexStorage2DEXT& c = GetCmdSpace<gles2::TexStorage2DEXT>();
+ c.Init(target, levels, internalFormat, width, height);
+ }
+
void SwapBuffers() {
gles2::SwapBuffers& c = GetCmdSpace<gles2::SwapBuffers>();
c.Init();
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index aff2e79..86d7ae1 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1224,6 +1224,25 @@ void RenderbufferStorageMultisampleEXT(
target, samples, internalformat, width, height);
}
+void TexStorage2DEXT(
+ GLenum target, GLsizei levels, GLint internalFormat, GLsizei width,
+ GLsizei height) {
+ GPU_CLIENT_LOG("[" << this << "] glTexStorage2DEXT(" << GLES2Util::GetStringTextureTarget(target) << ", " << levels << ", " << internalFormat << ", " << width << ", " << height << ")"); // NOLINT
+ if (levels < 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: levels < 0");
+ return;
+ }
+ if (width < 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: width < 0");
+ return;
+ }
+ if (height < 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: height < 0");
+ return;
+ }
+ helper_->TexStorage2DEXT(target, levels, internalFormat, width, height);
+}
+
void SwapBuffers();
GLuint GetMaxValueInBufferCHROMIUM(
diff --git a/gpu/command_buffer/common/gl_mock.h b/gpu/command_buffer/common/gl_mock.h
index 303fe9f..ae2259d 100644
--- a/gpu/command_buffer/common/gl_mock.h
+++ b/gpu/command_buffer/common/gl_mock.h
@@ -364,6 +364,10 @@ class MockGLInterface : public GLInterface {
MOCK_METHOD3(TexParameteriv, void(
GLenum target, GLenum pname, const GLint* params));
+ MOCK_METHOD5(TexStorage2DEXT, void(
+ GLenum target, GLsizei levels, GLenum internalformat,
+ GLsizei width, GLsizei height));
+
MOCK_METHOD9(TexSubImage2D, void(
GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
GLsizei height, GLenum format, GLenum type, const void* pixels));
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 2e726f4..fd82bea 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -8468,6 +8468,61 @@ COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, width) == 16,
COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, height) == 20,
OffsetOf_RenderbufferStorageMultisampleEXT_height_not_20);
+struct TexStorage2DEXT {
+ typedef TexStorage2DEXT ValueType;
+ static const CommandId kCmdId = kTexStorage2DEXT;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(
+ GLenum _target, GLsizei _levels, GLint _internalFormat, GLsizei _width,
+ GLsizei _height) {
+ SetHeader();
+ target = _target;
+ levels = _levels;
+ internalFormat = _internalFormat;
+ width = _width;
+ height = _height;
+ }
+
+ void* Set(
+ void* cmd, GLenum _target, GLsizei _levels, GLint _internalFormat,
+ GLsizei _width, GLsizei _height) {
+ static_cast<ValueType*>(
+ cmd)->Init(_target, _levels, _internalFormat, _width, _height);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+ int32 levels;
+ int32 internalFormat;
+ int32 width;
+ int32 height;
+};
+
+COMPILE_ASSERT(sizeof(TexStorage2DEXT) == 24,
+ Sizeof_TexStorage2DEXT_is_not_24);
+COMPILE_ASSERT(offsetof(TexStorage2DEXT, header) == 0,
+ OffsetOf_TexStorage2DEXT_header_not_0);
+COMPILE_ASSERT(offsetof(TexStorage2DEXT, target) == 4,
+ OffsetOf_TexStorage2DEXT_target_not_4);
+COMPILE_ASSERT(offsetof(TexStorage2DEXT, levels) == 8,
+ OffsetOf_TexStorage2DEXT_levels_not_8);
+COMPILE_ASSERT(offsetof(TexStorage2DEXT, internalFormat) == 12,
+ OffsetOf_TexStorage2DEXT_internalFormat_not_12);
+COMPILE_ASSERT(offsetof(TexStorage2DEXT, width) == 16,
+ OffsetOf_TexStorage2DEXT_width_not_16);
+COMPILE_ASSERT(offsetof(TexStorage2DEXT, height) == 20,
+ OffsetOf_TexStorage2DEXT_height_not_20);
+
struct SwapBuffers {
typedef SwapBuffers ValueType;
static const CommandId kCmdId = kSwapBuffers;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 9028708..1873878 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -3297,6 +3297,27 @@ TEST_F(GLES2FormatTest, RenderbufferStorageMultisampleEXT) {
next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, TexStorage2DEXT) {
+ TexStorage2DEXT& cmd = *GetBufferAs<TexStorage2DEXT>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ static_cast<GLsizei>(12),
+ static_cast<GLint>(13),
+ static_cast<GLsizei>(14),
+ static_cast<GLsizei>(15));
+ EXPECT_EQ(static_cast<uint32>(TexStorage2DEXT::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<GLsizei>(12), cmd.levels);
+ EXPECT_EQ(static_cast<GLint>(13), cmd.internalFormat);
+ EXPECT_EQ(static_cast<GLsizei>(14), cmd.width);
+ EXPECT_EQ(static_cast<GLsizei>(15), cmd.height);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd));
+}
+
TEST_F(GLES2FormatTest, SwapBuffers) {
SwapBuffers& cmd = *GetBufferAs<SwapBuffers>();
void* next_cmd = cmd.Set(
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 6c01a6c..e118b70 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -213,6 +213,7 @@
OP(GetTranslatedShaderSourceANGLE) /* 456 */ \
OP(PostSubBufferCHROMIUM) /* 457 */ \
OP(TexImageIOSurface2DCHROMIUM) /* 458 */ \
+ OP(TexStorage2DEXT) /* 459 */ \
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
index 1d8b50e..70fb34b 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_autogen.h
@@ -47,10 +47,12 @@ static std::string GetStringStringType(uint32 value);
static std::string GetStringTextureBindTarget(uint32 value);
static std::string GetStringTextureFormat(uint32 value);
static std::string GetStringTextureInternalFormat(uint32 value);
+static std::string GetStringTextureInternalFormatStorage(uint32 value);
static std::string GetStringTextureMagFilterMode(uint32 value);
static std::string GetStringTextureMinFilterMode(uint32 value);
static std::string GetStringTextureParameter(uint32 value);
static std::string GetStringTextureTarget(uint32 value);
+static std::string GetStringTextureUsage(uint32 value);
static std::string GetStringTextureWrapMode(uint32 value);
static std::string GetStringVertexAttribType(uint32 value);
static std::string GetStringVertexAttribute(uint32 value);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index 72ddb4a..572db3f 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -119,13 +119,19 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 1, "GL_ES_VERSION_2_0", },
{ 0x84F9, "GL_DEPTH_STENCIL_OES", },
{ 0x8368, "GL_UNSIGNED_INT_2_10_10_10_REV_EXT", },
+ { 0x8819, "GL_LUMINANCE_ALPHA32F_EXT", },
+ { 0x8818, "GL_LUMINANCE32F_EXT", },
{ 0x8363, "GL_UNSIGNED_SHORT_5_6_5", },
+ { 0x8814, "GL_RGBA32F_EXT", },
{ 0x84F2, "GL_ALL_COMPLETED_NV", },
- { 0x84F3, "GL_FENCE_STATUS_NV", },
+ { 0x8816, "GL_ALPHA32F_EXT", },
{ 0x84F4, "GL_FENCE_CONDITION_NV", },
{ 0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT", },
{ 0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT", },
+ { 0x881E, "GL_LUMINANCE16F_EXT", },
{ 0x84FA, "GL_UNSIGNED_INT_24_8_OES", },
+ { 0x881F, "GL_LUMINANCE_ALPHA16F_EXT", },
+ { 0x881A, "GL_RGBA16F_EXT", },
{ 0x84FE, "GL_TEXTURE_MAX_ANISOTROPY_EXT", },
{ 0x0901, "GL_CCW", },
{ 0x0900, "GL_CW", },
@@ -162,9 +168,12 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x00020000, "GL_STENCIL_BUFFER_BIT1_QCOM", },
{ 0x8D00, "GL_DEPTH_ATTACHMENT", },
{ 0x8FA0, "GL_PERFMON_GLOBAL_MODE_QCOM", },
+ { 0x8815, "GL_RGB32F_EXT", },
{ 0x813D, "GL_TEXTURE_MAX_LEVEL_APPLE", },
+ { 0x84F3, "GL_FENCE_STATUS_NV", },
{ 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED", },
{ 0x8CDF, "GL_MAX_COLOR_ATTACHMENTS_NV", },
+ { 0x803C, "GL_ALPHA8_EXT", },
{ 0x84F5, "GL_TEXTURE_RECTANGLE_ARB", },
{ 0x882A, "GL_DRAW_BUFFER5_NV", },
{ 0x80AA, "GL_SAMPLE_COVERAGE_VALUE", },
@@ -174,6 +183,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x882C, "GL_DRAW_BUFFER7_NV", },
{ 0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT", },
{ 0x0B74, "GL_DEPTH_FUNC", },
+ { 0x881B, "GL_RGB16F_EXT", },
{ 0x0B71, "GL_DEPTH_TEST", },
{ 0x0B70, "GL_DEPTH_RANGE", },
{ 0x0B73, "GL_DEPTH_CLEAR_VALUE", },
@@ -195,7 +205,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x00000400, "GL_STENCIL_BUFFER_BIT", },
{ 0x800A, "GL_FUNC_SUBTRACT", },
{ 0x8E2C, "GL_DEPTH_COMPONENT16_NONLINEAR_NV", },
- { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", },
+ { 0x8508, "GL_DECR_WRAP", },
{ 0x8006, "GL_FUNC_ADD", },
{ 0x8007, "GL_MIN_EXT", },
{ 0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA", },
@@ -281,12 +291,15 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x1405, "GL_UNSIGNED_INT", },
{ 0x1404, "GL_INT", },
{ 0x1406, "GL_FLOAT", },
+ { 0x8040, "GL_LUMINANCE8_EXT", },
+ { 0x8045, "GL_LUMINANCE8_ALPHA8_EXT", },
{ 0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME", },
{ 0x00040000, "GL_STENCIL_BUFFER_BIT2_QCOM", },
{ 0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE", },
{ 0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE", },
{ 0x0B90, "GL_STENCIL_TEST", },
{ 0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL", },
+ { 0x881C, "GL_ALPHA16F_EXT", },
{ 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES", },
{ 0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", },
{ 0x08000000, "GL_MULTISAMPLE_BUFFER_BIT3_QCOM", },
@@ -307,7 +320,11 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x8C0A, "GL_SGX_BINARY_IMG", },
{ 0x846D, "GL_ALIASED_POINT_SIZE_RANGE", },
{ 0x846E, "GL_ALIASED_LINE_WIDTH_RANGE", },
+ { 0x93A4, "GL_PACK_REVERSE_ROW_ORDER_ANGLE", },
+ { 0x93A1, "GL_BGRA8_EXT", },
{ 0x93A0, "GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE", },
+ { 0x93A3, "GL_FRAMEBUFFER_ATTACHMENT_ANGLE", },
+ { 0x93A2, "GL_TEXTURE_USAGE_ANGLE", },
{ 0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL", },
{ 0x8C01, "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG", },
{ 0x8C00, "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG", },
@@ -416,13 +433,16 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL", },
{ 0x2700, "GL_NEAREST_MIPMAP_NEAREST", },
{ 0x0B98, "GL_STENCIL_WRITEMASK", },
+ { 0x912F, "GL_TEXTURE_IMMUTABLE_FORMAT_EXT", },
{ 0x20000000, "GL_MULTISAMPLE_BUFFER_BIT5_QCOM", },
{ 0x0DE1, "GL_TEXTURE_2D", },
{ 0x80C9, "GL_BLEND_SRC_RGB", },
{ 0x80C8, "GL_BLEND_DST_RGB", },
+ { 0x8059, "GL_RGB10_A2_EXT", },
{ 0x8058, "GL_RGBA8_OES", },
{ 0x00002000, "GL_DEPTH_BUFFER_BIT5_QCOM", },
{ 0x8051, "GL_RGB8_OES", },
+ { 0x8052, "GL_RGB10_EXT", },
{ 0x8CAB, "GL_RENDERBUFFER_SAMPLES_ANGLE", },
{ 0x8057, "GL_RGB5_A1", },
{ 0x8056, "GL_RGBA4", },
@@ -445,7 +465,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = {
{ 0x8CE4, "GL_COLOR_ATTACHMENT4_NV", },
{ 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", },
{ 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS", },
- { 0x8508, "GL_DECR_WRAP", },
+ { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING", },
{ 0x8507, "GL_INCR_WRAP", },
{ 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING", },
{ 0x8894, "GL_ARRAY_BUFFER_BINDING", },
@@ -1031,6 +1051,21 @@ std::string GLES2Util::GetStringTextureInternalFormat(uint32 value) {
string_table, arraysize(string_table), value);
}
+std::string GLES2Util::GetStringTextureInternalFormatStorage(uint32 value) {
+ static EnumToString string_table[] = {
+ { GL_RGB565, "GL_RGB565" },
+ { GL_RGBA4, "GL_RGBA4" },
+ { GL_RGB5_A1, "GL_RGB5_A1" },
+ { GL_ALPHA8_EXT, "GL_ALPHA8_EXT" },
+ { GL_LUMINANCE8_EXT, "GL_LUMINANCE8_EXT" },
+ { GL_LUMINANCE8_ALPHA8_EXT, "GL_LUMINANCE8_ALPHA8_EXT" },
+ { GL_RGB8_OES, "GL_RGB8_OES" },
+ { GL_RGBA8_OES, "GL_RGBA8_OES" },
+ };
+ return GLES2Util::GetQualifiedEnumString(
+ string_table, arraysize(string_table), value);
+}
+
std::string GLES2Util::GetStringTextureMagFilterMode(uint32 value) {
static EnumToString string_table[] = {
{ GL_NEAREST, "GL_NEAREST" },
@@ -1078,6 +1113,15 @@ std::string GLES2Util::GetStringTextureTarget(uint32 value) {
string_table, arraysize(string_table), value);
}
+std::string GLES2Util::GetStringTextureUsage(uint32 value) {
+ static EnumToString string_table[] = {
+ { GL_NONE, "GL_NONE" },
+ { GL_FRAMEBUFFER_ATTACHMENT_ANGLE, "GL_FRAMEBUFFER_ATTACHMENT_ANGLE" },
+ };
+ return GLES2Util::GetQualifiedEnumString(
+ string_table, arraysize(string_table), value);
+}
+
std::string GLES2Util::GetStringTextureWrapMode(uint32 value) {
static EnumToString string_table[] = {
{ GL_CLAMP_TO_EDGE, "GL_CLAMP_TO_EDGE" },
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index c3cb1ee9..7bee2a8 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -405,6 +405,36 @@ void FeatureInfo::AddFeatures(const char* desired_features) {
validators_.pixel_store.AddValue(GL_PACK_REVERSE_ROW_ORDER_ANGLE);
validators_.g_l_state.AddValue(GL_PACK_REVERSE_ROW_ORDER_ANGLE);
}
+
+ if (ext.HaveAndDesire("GL_ANGLE_texture_usage")) {
+ AddExtensionString("GL_ANGLE_texture_usage");
+ validators_.texture_parameter.AddValue(GL_TEXTURE_USAGE_ANGLE);
+ }
+
+ if (ext.HaveAndDesire("GL_EXT_texture_storage")) {
+ AddExtensionString("GL_EXT_texture_storage");
+ validators_.texture_parameter.AddValue(GL_TEXTURE_IMMUTABLE_FORMAT_EXT);
+ if (enable_texture_format_bgra8888)
+ validators_.texture_internal_format_storage.AddValue(GL_BGRA8_EXT);
+ if (enable_texture_float) {
+ validators_.texture_internal_format_storage.AddValue(GL_RGBA32F_EXT);
+ validators_.texture_internal_format_storage.AddValue(GL_RGB32F_EXT);
+ validators_.texture_internal_format_storage.AddValue(GL_ALPHA32F_EXT);
+ validators_.texture_internal_format_storage.AddValue(
+ GL_LUMINANCE32F_EXT);
+ validators_.texture_internal_format_storage.AddValue(
+ GL_LUMINANCE_ALPHA32F_EXT);
+ }
+ if (enable_texture_half_float) {
+ validators_.texture_internal_format_storage.AddValue(GL_RGBA16F_EXT);
+ validators_.texture_internal_format_storage.AddValue(GL_RGB16F_EXT);
+ validators_.texture_internal_format_storage.AddValue(GL_ALPHA16F_EXT);
+ validators_.texture_internal_format_storage.AddValue(
+ GL_LUMINANCE16F_EXT);
+ validators_.texture_internal_format_storage.AddValue(
+ GL_LUMINANCE_ALPHA16F_EXT);
+ }
+ }
}
void FeatureInfo::AddExtensionString(const std::string& str) {
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index 55949d9..57bc592 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -81,6 +81,10 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) {
Not(HasSubstr("GL_CHROMIUM_texture_compression_dxt3")));
EXPECT_THAT(info_.extensions(),
Not(HasSubstr("GL_CHROMIUM_texture_compression_dxt5")));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_ANGLE_texture_usage")));
+ EXPECT_THAT(info_.extensions(),
+ Not(HasSubstr("GL_EXT_texture_storage")));
EXPECT_FALSE(info_.feature_flags().npot_ok);
EXPECT_FALSE(info_.feature_flags().chromium_webglsl);
EXPECT_FALSE(info_.validators()->compressed_texture_format.IsValid(
@@ -120,6 +124,8 @@ TEST_F(FeatureInfoTest, InitializeNoExtensions) {
GL_UNSIGNED_INT_24_8));
EXPECT_FALSE(info_.validators()->render_buffer_format.IsValid(
GL_DEPTH_COMPONENT24));
+ EXPECT_FALSE(info_.validators()->texture_parameter.IsValid(
+ GL_TEXTURE_USAGE_ANGLE));
}
TEST_F(FeatureInfoTest, InitializeNPOTExtensionGLES) {
diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h
index 8371b5f..d58e812 100644
--- a/gpu/command_buffer/service/gl_utils.h
+++ b/gpu/command_buffer/service/gl_utils.h
@@ -45,6 +45,27 @@
// GL_ANGLE_pack_reverse_row_order
#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4
+// GL_ANGLE_texture_usage
+#define GL_TEXTURE_USAGE_ANGLE 0x93A2
+#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3
+
+// GL_EXT_texture_storage
+#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F
+#define GL_ALPHA8_EXT 0x803C
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGBA32F_EXT 0x8814
+#define GL_RGB32F_EXT 0x8815
+#define GL_ALPHA32F_EXT 0x8816
+#define GL_LUMINANCE32F_EXT 0x8818
+#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
+#define GL_RGBA16F_EXT 0x881A
+#define GL_RGB16F_EXT 0x881B
+#define GL_ALPHA16F_EXT 0x881C
+#define GL_LUMINANCE16F_EXT 0x881E
+#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
+#define GL_BGRA8_EXT 0x93A1
+
#define GL_GLEXT_PROTOTYPES 1
// Define this for extra GL error debugging (slower).
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 3de264c..6c6e4e4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -751,6 +751,14 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
GLuint io_surface_id,
GLuint plane);
+ // Wrapper for TexStorage2DEXT.
+ void DoTexStorage2DEXT(
+ GLenum target,
+ GLint levels,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height);
+
// Creates a ProgramInfo for the given program.
ProgramManager::ProgramInfo* CreateProgramInfo(
GLuint client_id, GLuint service_id) {
@@ -3229,7 +3237,8 @@ void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) {
TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
- if (!info || !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) {
+ if (!info ||
+ !texture_manager()->MarkMipmapsGenerated(feature_info_, info, true)) {
SetGLError(GL_INVALID_OPERATION,
"glGenerateMipmaps: Can not generate mips for npot textures");
return;
@@ -6185,6 +6194,11 @@ error::Error GLES2DecoderImpl::DoCompressedTexImage2D(
"glCompressedTexImage2D: unknown texture target");
return error::kNoError;
}
+ if (info->IsImmutable()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glCompressedTexImage2D: texture is immutable");
+ return error::kNoError;
+ }
scoped_array<int8> zero;
if (!data) {
zero.reset(new int8[image_size]);
@@ -6360,6 +6374,12 @@ error::Error GLES2DecoderImpl::DoTexImage2D(
return error::kNoError;
}
+ if (info->IsImmutable()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glTexImage2D: texture is immutable");
+ return error::kNoError;
+ }
+
GLsizei tex_width = 0;
GLsizei tex_height = 0;
GLenum tex_type = 0;
@@ -6534,6 +6554,10 @@ void GLES2DecoderImpl::DoCopyTexImage2D(
"glCopyTexImage2D: unknown texture for target");
return;
}
+ if (info->IsImmutable()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glCopyTexImage2D: texture is immutable");
+ }
if (!texture_manager()->ValidForTarget(
feature_info_, target, level, width, height, 1) ||
border != 0) {
@@ -6729,7 +6753,8 @@ void GLES2DecoderImpl::DoTexSubImage2D(
}
// See if we can call glTexImage2D instead since it appears to be faster.
- if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0) {
+ if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0 &&
+ !info->IsImmutable()) {
GLsizei tex_width = 0;
GLsizei tex_height = 0;
bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height);
@@ -7684,6 +7709,137 @@ void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
#endif
}
+static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) {
+ switch (internalformat) {
+ case GL_RGB565:
+ return GL_RGB;
+ case GL_RGBA4:
+ return GL_RGBA;
+ case GL_RGB5_A1:
+ return GL_RGBA;
+ case GL_RGB8_OES:
+ return GL_RGB;
+ case GL_RGBA8_OES:
+ return GL_RGBA;
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return GL_LUMINANCE_ALPHA;
+ case GL_LUMINANCE8_EXT:
+ return GL_LUMINANCE;
+ case GL_ALPHA8_EXT:
+ return GL_ALPHA;
+ case GL_RGBA32F_EXT:
+ return GL_RGBA;
+ case GL_RGB32F_EXT:
+ return GL_RGB;
+ case GL_ALPHA32F_EXT:
+ return GL_ALPHA;
+ case GL_LUMINANCE32F_EXT:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ return GL_LUMINANCE_ALPHA;
+ case GL_RGBA16F_EXT:
+ return GL_RGBA;
+ case GL_RGB16F_EXT:
+ return GL_RGB;
+ case GL_ALPHA16F_EXT:
+ return GL_ALPHA;
+ case GL_LUMINANCE16F_EXT:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ return GL_LUMINANCE_ALPHA;
+ case GL_BGRA8_EXT:
+ return GL_BGRA_EXT;
+ default:
+ return GL_NONE;
+ }
+}
+
+static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) {
+ switch (internalformat) {
+ case GL_RGB565:
+ return GL_UNSIGNED_SHORT_5_6_5;
+ case GL_RGBA4:
+ return GL_UNSIGNED_SHORT_4_4_4_4;
+ case GL_RGB5_A1:
+ return GL_UNSIGNED_SHORT_5_5_5_1;
+ case GL_RGB8_OES:
+ return GL_UNSIGNED_BYTE;
+ case GL_RGBA8_OES:
+ return GL_UNSIGNED_BYTE;
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return GL_UNSIGNED_BYTE;
+ case GL_LUMINANCE8_EXT:
+ return GL_UNSIGNED_BYTE;
+ case GL_ALPHA8_EXT:
+ return GL_UNSIGNED_BYTE;
+ case GL_RGBA32F_EXT:
+ return GL_FLOAT;
+ case GL_RGB32F_EXT:
+ return GL_FLOAT;
+ case GL_ALPHA32F_EXT:
+ return GL_FLOAT;
+ case GL_LUMINANCE32F_EXT:
+ return GL_FLOAT;
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ return GL_FLOAT;
+ case GL_RGBA16F_EXT:
+ return GL_HALF_FLOAT_OES;
+ case GL_RGB16F_EXT:
+ return GL_HALF_FLOAT_OES;
+ case GL_ALPHA16F_EXT:
+ return GL_HALF_FLOAT_OES;
+ case GL_LUMINANCE16F_EXT:
+ return GL_HALF_FLOAT_OES;
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ return GL_HALF_FLOAT_OES;
+ case GL_BGRA8_EXT:
+ return GL_UNSIGNED_BYTE;
+ default:
+ return GL_NONE;
+ }
+}
+
+void GLES2DecoderImpl::DoTexStorage2DEXT(
+ GLenum target,
+ GLint levels,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height) {
+ if (!texture_manager()->ValidForTarget(
+ feature_info_, target, 0, width, height, 1) ||
+ TextureManager::ComputeMipMapCount(width, height, 1) < levels) {
+ SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: dimensions out of range");
+ return;
+ }
+ TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
+ if (!info) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glTexStorage2DEXT: unknown texture for target");
+ return;
+ }
+ if (info->IsAttachedToFramebuffer()) {
+ state_dirty_ = true;
+ }
+ if (info->IsImmutable()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glTexStorage2DEXT: texture is immutable");
+ return;
+ }
+ CopyRealGLErrorsToWrapper();
+ glTexStorage2DEXT(target, levels, internal_format, width, height);
+ GLenum error = PeekGLError();
+ if (error == GL_NO_ERROR) {
+ GLenum format = ExtractFormatFromStorageFormat(internal_format);
+ GLenum type = ExtractTypeFromStorageFormat(internal_format);
+ texture_manager()->SetLevelInfo(
+ feature_info_, info,
+ target, 0, format, width, height, 1, 0, format, type,
+ false);
+ texture_manager()->MarkMipmapsGenerated(feature_info_, info, false);
+ info->SetImmutable(true);
+ }
+
+}
// Include the auto-generated part of this file. We split this because it means
// we can easily edit the non-auto generated parts right here in this file
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 11a3caf..5c06a57 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -2542,6 +2542,39 @@ error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT(
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleTexStorage2DEXT(
+ uint32 immediate_data_size, const gles2::TexStorage2DEXT& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLsizei levels = static_cast<GLsizei>(c.levels);
+ GLint internalFormat = static_cast<GLint>(c.internalFormat);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (!validators_->texture_target.IsValid(target)) {
+ SetGLError(GL_INVALID_ENUM, "glTexStorage2DEXT: target GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ if (levels < 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: levels < 0");
+ return error::kNoError;
+ }
+ if (!validators_->texture_internal_format_storage.IsValid(internalFormat)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glTexStorage2DEXT: internalFormat GL_INVALID_VALUE");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: height < 0");
+ return error::kNoError;
+ }
+ DoTexStorage2DEXT(target, levels, internalFormat, width, height);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleGetMaxValueInBufferCHROMIUM(
uint32 immediate_data_size, const gles2::GetMaxValueInBufferCHROMIUM& c) {
GLuint buffer_id = c.buffer_id;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 9e587be..114bba1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -5599,6 +5599,17 @@ TEST_F(GLES2DecoderTest, DrawArraysClearsAfterTexImage2DNULLCubemap) {
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
+TEST_F(GLES2DecoderTest, TextureUsageAngleExtNotEnabledByDefault) {
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+
+ TexParameteri cmd;
+ cmd.Init(GL_TEXTURE_2D,
+ GL_TEXTURE_USAGE_ANGLE,
+ GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+ EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
+}
+
TEST_F(GLES2DecoderWithShaderTest,
DrawClearsAfterRenderbuffersWithMultipleAttachments) {
const GLuint kFBOClientTextureId = 4100;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index a94aff6..882ef3c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -1696,6 +1696,7 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
}
// TODO(gman): BlitFramebufferEXT
// TODO(gman): RenderbufferStorageMultisampleEXT
+// TODO(gman): TexStorage2DEXT
// TODO(gman): SwapBuffers
// TODO(gman): GetMaxValueInBufferCHROMIUM
// TODO(gman): GenSharedIdsCHROMIUM
@@ -1713,7 +1714,5 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
// TODO(gman): GetMultipleIntegervCHROMIUM
-// TODO(gman): GetProgramInfoCHROMIUM
-
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
index 8cc7d9b..518a588 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -10,6 +10,8 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
+// TODO(gman): GetProgramInfoCHROMIUM
+
// TODO(gman): CreateStreamTextureCHROMIUM
// TODO(gman): DestroyStreamTextureCHROMIUM
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
index ee335af..7e4fafc 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
@@ -50,10 +50,12 @@ ValueValidator<GLenum> texture_bind_target;
ValueValidator<GLint> texture_border;
ValueValidator<GLenum> texture_format;
ValueValidator<GLenum> texture_internal_format;
+ValueValidator<GLenum> texture_internal_format_storage;
ValueValidator<GLenum> texture_mag_filter_mode;
ValueValidator<GLenum> texture_min_filter_mode;
ValueValidator<GLenum> texture_parameter;
ValueValidator<GLenum> texture_target;
+ValueValidator<GLenum> texture_usage;
ValueValidator<GLenum> texture_wrap_mode;
ValueValidator<GLint> vertex_attrib_size;
ValueValidator<GLenum> vertex_attrib_type;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index 5008692..d89459c 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -382,6 +382,17 @@ static GLenum valid_texture_internal_format_table[] = {
GL_RGBA,
};
+static GLenum valid_texture_internal_format_storage_table[] = {
+ GL_RGB565,
+ GL_RGBA4,
+ GL_RGB5_A1,
+ GL_ALPHA8_EXT,
+ GL_LUMINANCE8_EXT,
+ GL_LUMINANCE8_ALPHA8_EXT,
+ GL_RGB8_OES,
+ GL_RGBA8_OES,
+};
+
static GLenum valid_texture_mag_filter_mode_table[] = {
GL_NEAREST,
GL_LINEAR,
@@ -413,6 +424,11 @@ static GLenum valid_texture_target_table[] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
};
+static GLenum valid_texture_usage_table[] = {
+ GL_NONE,
+ GL_FRAMEBUFFER_ATTACHMENT_ANGLE,
+};
+
static GLenum valid_texture_wrap_mode_table[] = {
GL_CLAMP_TO_EDGE,
GL_MIRRORED_REPEAT,
@@ -550,6 +566,9 @@ Validators::Validators()
texture_internal_format(
valid_texture_internal_format_table, arraysize(
valid_texture_internal_format_table)),
+ texture_internal_format_storage(
+ valid_texture_internal_format_storage_table, arraysize(
+ valid_texture_internal_format_storage_table)),
texture_mag_filter_mode(
valid_texture_mag_filter_mode_table, arraysize(
valid_texture_mag_filter_mode_table)),
@@ -561,6 +580,8 @@ Validators::Validators()
valid_texture_parameter_table)),
texture_target(
valid_texture_target_table, arraysize(valid_texture_target_table)),
+ texture_usage(
+ valid_texture_usage_table, arraysize(valid_texture_usage_table)),
texture_wrap_mode(
valid_texture_wrap_mode_table, arraysize(
valid_texture_wrap_mode_table)),
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index db0825c..03873d7 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -11,11 +11,6 @@
namespace gpu {
namespace gles2 {
-static GLsizei ComputeMipMapCount(
- GLsizei width, GLsizei height, GLsizei depth) {
- return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth));
-}
-
static size_t GLTargetToFaceIndex(GLenum target) {
switch (target) {
case GL_TEXTURE_2D:
@@ -111,7 +106,8 @@ bool TextureManager::TextureInfo::CanRender(
}
bool TextureManager::TextureInfo::MarkMipmapsGenerated(
- const FeatureInfo* feature_info) {
+ const FeatureInfo* feature_info,
+ bool cleared) {
if (!CanGenerateMipmaps(feature_info)) {
return false;
}
@@ -137,7 +133,7 @@ bool TextureManager::TextureInfo::MarkMipmapsGenerated(
info1.border,
info1.format,
info1.type,
- true);
+ cleared);
}
}
@@ -368,6 +364,12 @@ bool TextureManager::TextureInfo::SetParameter(
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
// Nothing to do for this case at the moment.
break;
+ case GL_TEXTURE_USAGE_ANGLE:
+ if (!feature_info->validators()->texture_usage.IsValid(param)) {
+ return false;
+ }
+ usage_ = param;
+ break;
default:
NOTREACHED();
return false;
@@ -789,7 +791,8 @@ bool TextureManager::SetParameter(
bool TextureManager::MarkMipmapsGenerated(
const FeatureInfo* feature_info,
- TextureManager::TextureInfo* info) {
+ TextureManager::TextureInfo* info,
+ bool cleared) {
DCHECK(info);
if (!info->CanRender(feature_info)) {
DCHECK_NE(0, num_unrenderable_textures_);
@@ -801,7 +804,7 @@ bool TextureManager::MarkMipmapsGenerated(
}
num_uncleared_mips_ -= info->num_uncleared_mips();
DCHECK_GE(num_uncleared_mips_, 0);
- bool result = info->MarkMipmapsGenerated(feature_info);
+ bool result = info->MarkMipmapsGenerated(feature_info, cleared);
num_uncleared_mips_ += info->num_uncleared_mips();
if (!info->CanRender(feature_info)) {
++num_unrenderable_textures_;
@@ -867,6 +870,12 @@ bool TextureManager::GetClientId(GLuint service_id, GLuint* client_id) const {
return false;
}
+GLsizei TextureManager::ComputeMipMapCount(
+ GLsizei width, GLsizei height, GLsizei depth) {
+ return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth));
+}
+
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index aaeed80..e38706a 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -40,6 +40,7 @@ class TextureManager {
mag_filter_(GL_LINEAR),
wrap_s_(GL_REPEAT),
wrap_t_(GL_REPEAT),
+ usage_(GL_NONE),
max_level_set_(-1),
texture_complete_(false),
cube_complete_(false),
@@ -47,7 +48,8 @@ class TextureManager {
has_been_bound_(false),
framebuffer_attachment_count_(0),
owned_(true),
- stream_texture_(false) {
+ stream_texture_(false),
+ immutable_(false) {
}
GLenum min_filter() const {
@@ -66,6 +68,10 @@ class TextureManager {
return wrap_t_;
}
+ GLenum usage() const {
+ return usage_;
+ }
+
int num_uncleared_mips() const {
return num_uncleared_mips_;
}
@@ -169,6 +175,15 @@ class TextureManager {
return stream_texture_;
}
+ void SetImmutable(bool immutable) {
+ DCHECK(!immutable_);
+ immutable_ = immutable;
+ }
+
+ bool IsImmutable() {
+ return immutable_;
+ }
+
// Whether a particular level/face is cleared.
bool IsLevelCleared(GLenum target, GLint level);
@@ -239,7 +254,7 @@ class TextureManager {
const FeatureInfo* feature_info, GLenum pname, GLint param);
// Makes each of the mip levels as though they were generated.
- bool MarkMipmapsGenerated(const FeatureInfo* feature_info);
+ bool MarkMipmapsGenerated(const FeatureInfo* feature_info, bool cleared);
void MarkAsDeleted() {
service_id_ = 0;
@@ -282,6 +297,7 @@ class TextureManager {
GLenum mag_filter_;
GLenum wrap_s_;
GLenum wrap_t_;
+ GLenum usage_;
// The maximum level that has been set.
GLint max_level_set_;
@@ -308,6 +324,10 @@ class TextureManager {
// Whether this is a special streaming texture.
bool stream_texture_;
+ // Whether the texture is immutable and no further changes to the format
+ // or dimensions of the texture object can be made.
+ bool immutable_;
+
DISALLOW_COPY_AND_ASSIGN(TextureInfo);
};
@@ -344,6 +364,10 @@ class TextureManager {
}
}
+ // Returns the maxium number of levels a texture of the given size can have.
+ static GLsizei ComputeMipMapCount(
+ GLsizei width, GLsizei height, GLsizei depth);
+
// Checks if a dimensions are valid for a given target.
bool ValidForTarget(
const FeatureInfo* feature_info,
@@ -385,7 +409,8 @@ class TextureManager {
// Makes each of the mip levels as though they were generated.
// Returns false if that's not allowed for the given texture.
- bool MarkMipmapsGenerated(const FeatureInfo* feature_info, TextureInfo* info);
+ bool MarkMipmapsGenerated(const FeatureInfo* feature_info, TextureInfo* info,
+ bool cleared);
// Clears any uncleared renderable levels.
bool ClearRenderableLevels(GLES2Decoder* decoder, TextureInfo* info);
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 4481567..d579ce2 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -124,6 +124,24 @@ TEST_F(TextureManagerTest, SetParameter) {
EXPECT_EQ(static_cast<GLenum>(GL_CLAMP_TO_EDGE), info->wrap_t());
}
+TEST_F(TextureManagerTest, TextureUsageExt) {
+ TestHelper::SetupTextureManagerInitExpectations(gl_.get(),
+ "GL_ANGLE_texture_usage");
+ manager_.Initialize(&feature_info_);
+ const GLuint kClient1Id = 1;
+ const GLuint kService1Id = 11;
+ // Check we can create texture.
+ manager_.CreateTextureInfo(&feature_info_, kClient1Id, kService1Id);
+ // Check texture got created.
+ TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id);
+ ASSERT_TRUE(info != NULL);
+ EXPECT_TRUE(manager_.SetParameter(
+ &feature_info_, info, GL_TEXTURE_USAGE_ANGLE,
+ GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
+ EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_ATTACHMENT_ANGLE),
+ info->usage());
+}
+
TEST_F(TextureManagerTest, Destroy) {
const GLuint kClient1Id = 1;
const GLuint kService1Id = 11;
@@ -323,6 +341,7 @@ TEST_F(TextureInfoTest, Basic) {
EXPECT_EQ(0, info_->num_uncleared_mips());
EXPECT_FALSE(info_->CanRender(&feature_info_));
EXPECT_TRUE(info_->SafeToRenderFrom());
+ EXPECT_FALSE(info_->IsImmutable());
EXPECT_EQ(static_cast<GLenum>(GL_NEAREST_MIPMAP_LINEAR), info_->min_filter());
EXPECT_EQ(static_cast<GLenum>(GL_LINEAR), info_->mag_filter());
EXPECT_EQ(static_cast<GLenum>(GL_REPEAT), info_->wrap_s());
@@ -354,7 +373,7 @@ TEST_F(TextureInfoTest, POT2D) {
EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
@@ -371,7 +390,7 @@ TEST_F(TextureInfoTest, POT2D) {
GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
EXPECT_TRUE(info_->CanRender(&feature_info_));
EXPECT_TRUE(info_->texture_complete());
EXPECT_FALSE(manager_.HaveUnrenderableTextures());
@@ -383,7 +402,7 @@ TEST_F(TextureInfoTest, UnusedMips) {
// Set level zero to large size.
manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
EXPECT_FALSE(info_->npot());
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
@@ -391,7 +410,7 @@ TEST_F(TextureInfoTest, UnusedMips) {
// Set level zero to large smaller (levels unused mips)
manager_.SetLevelInfo(&feature_info_, info_,
GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
EXPECT_FALSE(info_->npot());
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
@@ -457,7 +476,7 @@ TEST_F(TextureInfoTest, NPOT2DNPOTOK) {
EXPECT_TRUE(info->CanGenerateMipmaps(&feature_info));
EXPECT_FALSE(info->CanRender(&feature_info));
EXPECT_TRUE(manager.HaveUnrenderableTextures());
- EXPECT_TRUE(manager.MarkMipmapsGenerated(&feature_info, info));
+ EXPECT_TRUE(manager.MarkMipmapsGenerated(&feature_info, info, true));
EXPECT_TRUE(info->texture_complete());
EXPECT_TRUE(info->CanRender(&feature_info));
EXPECT_FALSE(manager.HaveUnrenderableTextures());
@@ -524,7 +543,7 @@ TEST_F(TextureInfoTest, POTCubeMap) {
EXPECT_TRUE(manager_.HaveUnrenderableTextures());
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
EXPECT_TRUE(info_->CanRender(&feature_info_));
@@ -544,7 +563,7 @@ TEST_F(TextureInfoTest, POTCubeMap) {
3, GL_RGBA, 4, 4, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
EXPECT_TRUE(info_->CanGenerateMipmaps(&feature_info_));
// Make mips.
- EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_));
+ EXPECT_TRUE(manager_.MarkMipmapsGenerated(&feature_info_, info_, true));
EXPECT_TRUE(info_->texture_complete());
EXPECT_TRUE(info_->cube_complete());
}
@@ -778,7 +797,7 @@ TEST_F(TextureInfoTest, SafeUnsafe) {
EXPECT_TRUE(manager_.HaveUnsafeTextures());
EXPECT_TRUE(manager_.HaveUnclearedMips());
EXPECT_EQ(1, info_->num_uncleared_mips());
- manager_.MarkMipmapsGenerated(&feature_info_, info_);
+ manager_.MarkMipmapsGenerated(&feature_info_, info_, true);
EXPECT_TRUE(info_->SafeToRenderFrom());
EXPECT_FALSE(manager_.HaveUnsafeTextures());
EXPECT_FALSE(manager_.HaveUnclearedMips());