diff options
author | vangelis@chromium.org <vangelis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 17:26:17 +0000 |
---|---|---|
committer | vangelis@chromium.org <vangelis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 17:26:17 +0000 |
commit | 97dc7cbe1b802facd4ccf92c6f7da78bd5a8ce51 (patch) | |
tree | 93e396f7cef6348bbebcd3c83cbdf7eb023d0d3f /gpu/command_buffer | |
parent | fa8e6464f65a0f0304ea199d04ca531dbab79f99 (diff) | |
download | chromium_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')
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()); |