diff options
author | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-28 22:04:42 +0000 |
---|---|---|
committer | sievers@chromium.org <sievers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-28 22:04:42 +0000 |
commit | b0af4f572f1e082a876a1e87eb2933c5876e0ba0 (patch) | |
tree | dfa113ede64291cf4fd1604d992e64fb901fef79 /gpu | |
parent | a09ef7e5fade0f4f62157aae616f3929b8cbba53 (diff) | |
download | chromium_src-b0af4f572f1e082a876a1e87eb2933c5876e0ba0.zip chromium_src-b0af4f572f1e082a876a1e87eb2933c5876e0ba0.tar.gz chromium_src-b0af4f572f1e082a876a1e87eb2933c5876e0ba0.tar.bz2 |
External stream texture support.
This adds a GL_CHROMIUM_stream_texture extension with an abstract interface
that can be used to allow a consumer to render from a stream of textures being produced externally.
It adds the following functionality:
* GLuint glCreateStreamTextureCHROMIUM(GLuint texture)
This API takes a texture id and creates a StreamTexture object associated with the texture in the GPU process that can be implemented in a platform-specific way.
The returned handle is supposed to identify the stream endpoint. Connecting this to a producer is outside the scope of this change.
* GLvoid glDestroyStreamTextureCHROMIUM(GLuint texture)
Deletes the StreamTexture object associated with the texture and marks the texture as not special anymore.
* BindTexture() will invoke method StreamTexture::Update() if the target is GL_TEXTURE_EXTERNAL_OES and the texture is marked as 'stream texture'.
TEST=added unit tests
Review URL: http://codereview.chromium.org/7754033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103191 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
32 files changed, 774 insertions, 78 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index f4cd5f2..00c152b 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -220,8 +220,8 @@ GL_APICALL void GL_APIENTRY glRateLimitOffscreenContextCHROMIUM (void); GL_APICALL void GL_APIENTRY glGetMultipleIntegervCHROMIUM (const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size); GL_APICALL void GL_APIENTRY glGetProgramInfoCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); GL_APICALL void GL_APIENTRY glPlaceholder447CHROMIUM (void); -GL_APICALL void GL_APIENTRY glPlaceholder451CHROMIUM (void); -GL_APICALL void GL_APIENTRY glPlaceholder452CHROMIUM (void); +GL_APICALL GLuint GL_APIENTRY glCreateStreamTextureCHROMIUM (GLuint texture); +GL_APICALL void GL_APIENTRY glDestroyStreamTextureCHROMIUM (GLuint texture); GL_APICALL void GL_APIENTRY glPlaceholder453CHROMIUM (void); """ @@ -426,8 +426,8 @@ _CMD_ID_TABLE = { 'ResizeCHROMIUM': 448, 'GetRequestableExtensionsCHROMIUM': 449, 'RequestExtensionCHROMIUM': 450, - 'Placeholder451CHROMIUM': 451, - 'Placeholder452CHROMIUM': 452, + 'CreateStreamTextureCHROMIUM': 451, + 'DestroyStreamTextureCHROMIUM': 452, 'Placeholder453CHROMIUM': 453, 'GetMultipleIntegervCHROMIUM': 454, 'GetProgramInfoCHROMIUM': 455, @@ -1753,16 +1753,23 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, }, - 'Placeholder451CHROMIUM': { - 'type': 'UnknownCommand', + 'CreateStreamTextureCHROMIUM': { + 'type': 'Custom', + 'cmd_args': 'GLuint client_id, void* result', + 'result': ['GLuint'], + 'immediate': False, + 'impl_func': False, + 'expectation': False, 'extension': True, 'chromium': True, - }, - 'Placeholder452CHROMIUM': { - 'type': 'UnknownCommand', + }, + 'DestroyStreamTextureCHROMIUM': { + 'type': 'Custom', + 'impl_func': False, + 'expectation': False, 'extension': True, 'chromium': True, - }, + }, 'Placeholder453CHROMIUM': { 'type': 'UnknownCommand', 'extension': True, diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 4ba96ac..265b4fe 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -575,6 +575,12 @@ void GLES2GetProgramInfoCHROMIUM( GLuint program, GLsizei bufsize, GLsizei* size, void* info) { gles2::GetGLContext()->GetProgramInfoCHROMIUM(program, bufsize, size, info); } +GLuint GLES2CreateStreamTextureCHROMIUM(GLuint texture) { + return gles2::GetGLContext()->CreateStreamTextureCHROMIUM(texture); +} +void GLES2DestroyStreamTextureCHROMIUM(GLuint texture) { + gles2::GetGLContext()->DestroyStreamTextureCHROMIUM(texture); +} #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index 384f4ac..82bf39a 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -1228,5 +1228,18 @@ c.Init(program, bucket_id); } + void CreateStreamTextureCHROMIUM( + GLuint client_id, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::CreateStreamTextureCHROMIUM& c = + GetCmdSpace<gles2::CreateStreamTextureCHROMIUM>(); + c.Init(client_id, result_shm_id, result_shm_offset); + } + + void DestroyStreamTextureCHROMIUM(GLuint texture) { + gles2::DestroyStreamTextureCHROMIUM& c = + GetCmdSpace<gles2::DestroyStreamTextureCHROMIUM>(); + c.Init(texture); + } + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 29db8d3..1ccccd9 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -2630,5 +2630,28 @@ void GLES2Implementation::GetProgramInfoCHROMIUM( memcpy(info, &result[0], result.size()); } +GLuint GLES2Implementation::CreateStreamTextureCHROMIUM(GLuint texture) { + GPU_CLIENT_LOG("[" << this << "] CreateStreamTextureCHROMIUM(" + << texture << ")"); + TRACE_EVENT0("gpu", "GLES2::CreateStreamTextureCHROMIUM"); + typedef CreateStreamTextureCHROMIUM::Result Result; + Result* result = GetResultAs<Result*>(); + *result = GL_ZERO; + + helper_->CreateStreamTextureCHROMIUM(texture, + result_shm_id(), + result_shm_offset()); + WaitForCmd(); + + return *result; +} + +void GLES2Implementation::DestroyStreamTextureCHROMIUM(GLuint texture) { + GPU_CLIENT_LOG("[" << this << "] DestroyStreamTextureCHROMIUM(" + << texture << ")"); + TRACE_EVENT0("gpu", "GLES2::DestroyStreamTextureCHROMIUM"); + helper_->DestroyStreamTextureCHROMIUM(texture); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index b6d2278..fc2dc5c 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -1268,5 +1268,9 @@ void GetMultipleIntegervCHROMIUM( void GetProgramInfoCHROMIUM( GLuint program, GLsizei bufsize, GLsizei* size, void* info); +GLuint CreateStreamTextureCHROMIUM(GLuint texture); + +void DestroyStreamTextureCHROMIUM(GLuint texture); + #endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_ diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 324d51f..9320cee 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -1802,6 +1802,43 @@ TEST_F(GLES2ImplementationStrictSharedTest, CanNotDeleteIdsWeDidNotCreate) { EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); } +TEST_F(GLES2ImplementationTest, CreateStreamTextureCHROMIUM) { + const GLuint kTextureId = 123; + const GLuint kResult = 456; + const uint32 kResultOffset = 0; + + struct Cmds { + CreateStreamTextureCHROMIUM create_stream; + }; + + Cmds expected; + expected.create_stream.Init(kTextureId, kTransferBufferId, kResultOffset); + + EXPECT_CALL(*command_buffer_, OnFlush(_)) + .WillOnce(SetMemoryAtOffset(kResultOffset, kResult)) + .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) + .RetiresOnSaturation(); + + GLuint handle = gl_->CreateStreamTextureCHROMIUM(kTextureId); + EXPECT_EQ(handle, kResult); + EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + +TEST_F(GLES2ImplementationTest, DestroyStreamTextureCHROMIUM) { + const GLuint kTextureHandle = 456; + + struct Cmds { + DestroyStreamTextureCHROMIUM destroy_stream; + }; + + Cmds expected; + expected.destroy_stream.Init(kTextureHandle); + + gl_->DestroyStreamTextureCHROMIUM(kTextureHandle); + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index 0c29aa7..1c1b9db 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -9015,11 +9015,13 @@ COMPILE_ASSERT(sizeof(Placeholder447CHROMIUM) == 4, COMPILE_ASSERT(offsetof(Placeholder447CHROMIUM, header) == 0, OffsetOf_Placeholder447CHROMIUM_header_not_0); -struct Placeholder451CHROMIUM { - typedef Placeholder451CHROMIUM ValueType; - static const CommandId kCmdId = kPlaceholder451CHROMIUM; +struct CreateStreamTextureCHROMIUM { + typedef CreateStreamTextureCHROMIUM ValueType; + static const CommandId kCmdId = kCreateStreamTextureCHROMIUM; static const cmd::ArgFlags kArgFlags = cmd::kFixed; + typedef GLuint Result; + static uint32 ComputeSize() { return static_cast<uint32>(sizeof(ValueType)); // NOLINT } @@ -9028,26 +9030,42 @@ struct Placeholder451CHROMIUM { header.SetCmd<ValueType>(); } - void Init() { + void Init( + GLuint _client_id, uint32 _result_shm_id, uint32 _result_shm_offset) { SetHeader(); + client_id = _client_id; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; } - void* Set(void* cmd) { - static_cast<ValueType*>(cmd)->Init(); + void* Set( + void* cmd, GLuint _client_id, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_client_id, _result_shm_id, _result_shm_offset); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; + uint32 client_id; + uint32 result_shm_id; + uint32 result_shm_offset; }; -COMPILE_ASSERT(sizeof(Placeholder451CHROMIUM) == 4, - Sizeof_Placeholder451CHROMIUM_is_not_4); -COMPILE_ASSERT(offsetof(Placeholder451CHROMIUM, header) == 0, - OffsetOf_Placeholder451CHROMIUM_header_not_0); +COMPILE_ASSERT(sizeof(CreateStreamTextureCHROMIUM) == 16, + Sizeof_CreateStreamTextureCHROMIUM_is_not_16); +COMPILE_ASSERT(offsetof(CreateStreamTextureCHROMIUM, header) == 0, + OffsetOf_CreateStreamTextureCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(CreateStreamTextureCHROMIUM, client_id) == 4, + OffsetOf_CreateStreamTextureCHROMIUM_client_id_not_4); +COMPILE_ASSERT(offsetof(CreateStreamTextureCHROMIUM, result_shm_id) == 8, + OffsetOf_CreateStreamTextureCHROMIUM_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(CreateStreamTextureCHROMIUM, result_shm_offset) == 12, + OffsetOf_CreateStreamTextureCHROMIUM_result_shm_offset_not_12); -struct Placeholder452CHROMIUM { - typedef Placeholder452CHROMIUM ValueType; - static const CommandId kCmdId = kPlaceholder452CHROMIUM; +struct DestroyStreamTextureCHROMIUM { + typedef DestroyStreamTextureCHROMIUM ValueType; + static const CommandId kCmdId = kDestroyStreamTextureCHROMIUM; static const cmd::ArgFlags kArgFlags = cmd::kFixed; static uint32 ComputeSize() { @@ -9058,22 +9076,26 @@ struct Placeholder452CHROMIUM { header.SetCmd<ValueType>(); } - void Init() { + void Init(GLuint _texture) { SetHeader(); + texture = _texture; } - void* Set(void* cmd) { - static_cast<ValueType*>(cmd)->Init(); + void* Set(void* cmd, GLuint _texture) { + static_cast<ValueType*>(cmd)->Init(_texture); return NextCmdAddress<ValueType>(cmd); } gpu::CommandHeader header; + uint32 texture; }; -COMPILE_ASSERT(sizeof(Placeholder452CHROMIUM) == 4, - Sizeof_Placeholder452CHROMIUM_is_not_4); -COMPILE_ASSERT(offsetof(Placeholder452CHROMIUM, header) == 0, - OffsetOf_Placeholder452CHROMIUM_header_not_0); +COMPILE_ASSERT(sizeof(DestroyStreamTextureCHROMIUM) == 8, + Sizeof_DestroyStreamTextureCHROMIUM_is_not_8); +COMPILE_ASSERT(offsetof(DestroyStreamTextureCHROMIUM, header) == 0, + OffsetOf_DestroyStreamTextureCHROMIUM_header_not_0); +COMPILE_ASSERT(offsetof(DestroyStreamTextureCHROMIUM, texture) == 4, + OffsetOf_DestroyStreamTextureCHROMIUM_texture_not_4); struct Placeholder453CHROMIUM { typedef Placeholder453CHROMIUM ValueType; 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 d546044..1983e72 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -3500,24 +3500,34 @@ TEST_F(GLES2FormatTest, Placeholder447CHROMIUM) { next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, Placeholder451CHROMIUM) { - Placeholder451CHROMIUM& cmd = *GetBufferAs<Placeholder451CHROMIUM>(); +TEST_F(GLES2FormatTest, CreateStreamTextureCHROMIUM) { + CreateStreamTextureCHROMIUM& cmd = + *GetBufferAs<CreateStreamTextureCHROMIUM>(); void* next_cmd = cmd.Set( - &cmd); - EXPECT_EQ(static_cast<uint32>(Placeholder451CHROMIUM::kCmdId), + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(static_cast<uint32>(CreateStreamTextureCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.client_id); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); CheckBytesWrittenMatchesExpectedSize( next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, Placeholder452CHROMIUM) { - Placeholder452CHROMIUM& cmd = *GetBufferAs<Placeholder452CHROMIUM>(); +TEST_F(GLES2FormatTest, DestroyStreamTextureCHROMIUM) { + DestroyStreamTextureCHROMIUM& cmd = + *GetBufferAs<DestroyStreamTextureCHROMIUM>(); void* next_cmd = cmd.Set( - &cmd); - EXPECT_EQ(static_cast<uint32>(Placeholder452CHROMIUM::kCmdId), + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(static_cast<uint32>(DestroyStreamTextureCHROMIUM::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); + EXPECT_EQ(static_cast<GLuint>(11), cmd.texture); CheckBytesWrittenMatchesExpectedSize( next_cmd, sizeof(cmd)); } diff --git a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h index cae5339..9597b12f 100644 --- a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h @@ -407,10 +407,12 @@ TEST(GLES2CommandIdTest, CommandIdsMatch) { GLES2_GetProgramInfoCHROMIUM_kCmdId_mismatch); COMPILE_ASSERT(Placeholder447CHROMIUM::kCmdId == 447, GLES2_Placeholder447CHROMIUM_kCmdId_mismatch); - COMPILE_ASSERT(Placeholder451CHROMIUM::kCmdId == 451, - GLES2_Placeholder451CHROMIUM_kCmdId_mismatch); - COMPILE_ASSERT(Placeholder452CHROMIUM::kCmdId == 452, - GLES2_Placeholder452CHROMIUM_kCmdId_mismatch); + COMPILE_ASSERT(CreateStreamTextureCHROMIUM::kCmdId == 451, + GLES2_CreateStreamTextureCHROMIUM_kCmdId_mismatch); + COMPILE_ASSERT(DestroyStreamTextureCHROMIUM::kCmdId == 452, + GLES2_DestroyStreamTextureCHROMIUM_kCmdId_mismatch); + COMPILE_ASSERT(Placeholder453CHROMIUM::kCmdId == 453, + GLES2_Placeholder453CHROMIUM_kCmdId_mismatch); } #endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_ID_TEST_AUTOGEN_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 1063edf..2594aba 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -205,8 +205,8 @@ OP(ResizeCHROMIUM) /* 448 */ \ OP(GetRequestableExtensionsCHROMIUM) /* 449 */ \ OP(RequestExtensionCHROMIUM) /* 450 */ \ - OP(Placeholder451CHROMIUM) /* 451 */ \ - OP(Placeholder452CHROMIUM) /* 452 */ \ + OP(CreateStreamTextureCHROMIUM) /* 451 */ \ + OP(DestroyStreamTextureCHROMIUM) /* 452 */ \ OP(Placeholder453CHROMIUM) /* 453 */ \ OP(GetMultipleIntegervCHROMIUM) /* 454 */ \ OP(GetProgramInfoCHROMIUM) /* 455 */ \ diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 2270a38..c90d5a3 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -338,6 +338,11 @@ void FeatureInfo::AddFeatures(const char* desired_features) { validators_.g_l_state.AddValue(GL_TEXTURE_BINDING_EXTERNAL_OES); } + if (ext.Desire("GL_CHROMIUM_stream_texture")) { + AddExtensionString("GL_CHROMIUM_stream_texture"); + feature_flags_.chromium_stream_texture = true; + } + // TODO(gman): Add support for these extensions. // GL_OES_depth32 // GL_OES_element_index_uint diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index 7a087bd..93913f6 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -23,7 +23,8 @@ class FeatureInfo { npot_ok(false), enable_texture_float_linear(false), enable_texture_half_float_linear(false), - chromium_webglsl(false) { + chromium_webglsl(false), + chromium_stream_texture(false) { } bool chromium_framebuffer_multisample; @@ -33,6 +34,7 @@ class FeatureInfo { bool enable_texture_float_linear; bool enable_texture_half_float_linear; bool chromium_webglsl; + bool chromium_stream_texture; }; FeatureInfo(); diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 5f87e92..eb944a8 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -60,6 +60,7 @@ TEST_F(FeatureInfoTest, Basic) { EXPECT_FALSE(info_.feature_flags().enable_texture_half_float_linear); EXPECT_FALSE(info_.feature_flags().chromium_webglsl); EXPECT_FALSE(info_.feature_flags().oes_egl_image_external); + EXPECT_FALSE(info_.feature_flags().chromium_stream_texture); } TEST_F(FeatureInfoTest, InitializeNoExtensions) { @@ -427,6 +428,14 @@ TEST_F(FeatureInfoTest, InitializeOES_EGL_image_external) { GL_TEXTURE_BINDING_EXTERNAL_OES)); } +TEST_F(FeatureInfoTest, InitializeCHROMIUM_stream_texture) { + SetupInitExpectations("GL_CHROMIUM_stream_texture"); + info_.Initialize(NULL); + EXPECT_THAT(info_.extensions(), + HasSubstr("GL_CHROMIUM_stream_texture")); + EXPECT_TRUE(info_.feature_flags().chromium_stream_texture); +} + } // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc index 316bc32..909a451 100644 --- a/gpu/command_buffer/service/framebuffer_manager.cc +++ b/gpu/command_buffer/service/framebuffer_manager.cc @@ -47,6 +47,10 @@ class RenderbufferAttachment return false; } + virtual bool CanRenderTo() const { + return true; + } + RenderbufferManager::RenderbufferInfo* render_buffer() const { return render_buffer_.get(); } @@ -111,6 +115,10 @@ class TextureAttachment return texture_.get(); } + virtual bool CanRenderTo() const { + return texture_->CanRenderTo(); + } + private: TextureManager::TextureInfo::Ref texture_; GLenum target_; @@ -203,6 +211,9 @@ bool FramebufferManager::FramebufferInfo::IsNotComplete() const { if (attachment->width() == 0 || attachment->height() == 0) { return true; } + if (!attachment->CanRenderTo()) { + return true; + } } return false; } diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h index 0641c35..737dfff 100644 --- a/gpu/command_buffer/service/framebuffer_manager.h +++ b/gpu/command_buffer/service/framebuffer_manager.h @@ -37,6 +37,7 @@ class FramebufferManager { virtual bool cleared() const = 0; virtual void set_cleared() = 0; virtual bool IsTexture(TextureManager::TextureInfo* texture) const = 0; + virtual bool CanRenderTo() const = 0; }; explicit FramebufferInfo(GLuint service_id); diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc index 77c6622..eec9a33 100644 --- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc +++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc @@ -303,7 +303,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) { EXPECT_TRUE(info_->IsNotComplete()); EXPECT_EQ(static_cast<GLenum>(0), info_->GetColorAttachmentFormat()); - tex_manager.SetInfoTarget(tex_info1, GL_TEXTURE_2D); + tex_manager.SetInfoTarget(&feature_info, tex_info1, GL_TEXTURE_2D); tex_manager.SetLevelInfo( &feature_info, tex_info1, GL_TEXTURE_2D, kLevel1, kFormat1, kWidth1, kHeight1, kDepth, kBorder, kFormat1, kType); @@ -325,7 +325,7 @@ TEST_F(FramebufferInfoTest, AttachTexture) { TextureManager::TextureInfo* tex_info2 = tex_manager.GetTextureInfo(kTextureClient2Id); ASSERT_TRUE(tex_info2 != NULL); - tex_manager.SetInfoTarget(tex_info2, GL_TEXTURE_2D); + tex_manager.SetInfoTarget(&feature_info, tex_info2, GL_TEXTURE_2D); tex_manager.SetLevelInfo( &feature_info, tex_info2, GL_TEXTURE_2D, kLevel2, kFormat2, kWidth2, kHeight2, kDepth, kBorder, kFormat2, kType); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index d6c513e..4f18d89 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -34,6 +34,8 @@ #include "gpu/command_buffer/service/renderbuffer_manager.h" #include "gpu/command_buffer/service/shader_manager.h" #include "gpu/command_buffer/service/shader_translator.h" +#include "gpu/command_buffer/service/stream_texture.h" +#include "gpu/command_buffer/service/stream_texture_manager.h" #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/command_buffer/service/vertex_attrib_manager.h" #include "ui/gfx/gl/gl_context.h" @@ -481,6 +483,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, virtual void SetSwapBuffersCallback(Callback0::Type* callback); #endif + virtual void SetStreamTextureManager(StreamTextureManager* manager); virtual bool GetServiceTextureId(uint32 client_texture_id, uint32* service_texture_id); @@ -1288,6 +1291,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, scoped_ptr<Callback0::Type> swap_buffers_callback_; #endif + StreamTextureManager* stream_texture_manager_; + // The format of the back buffer_ GLenum back_buffer_color_format_; bool back_buffer_has_depth_; @@ -1670,6 +1675,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) offscreen_target_stencil_format_(0), offscreen_target_samples_(0), offscreen_saved_color_format_(0), + stream_texture_manager_(NULL), back_buffer_color_format_(0), back_buffer_has_depth_(false), back_buffer_has_stencil_(false), @@ -2129,6 +2135,9 @@ void GLES2DecoderImpl::DeleteTexturesHelper( state_dirty_ = true; } GLuint service_id = info->service_id(); + if (info->IsStreamTexture() && stream_texture_manager_) { + stream_texture_manager_->DestroyStreamTexture(service_id); + } glDeleteTextures(1, &service_id); RemoveTextureInfo(client_ids[ii]); } @@ -2301,6 +2310,10 @@ void GLES2DecoderImpl::SetSwapBuffersCallback(Callback0::Type* callback) { } #endif +void GLES2DecoderImpl::SetStreamTextureManager(StreamTextureManager* manager) { + stream_texture_manager_ = manager; +} + bool GLES2DecoderImpl::GetServiceTextureId(uint32 client_texture_id, uint32* service_texture_id) { TextureManager::TextureInfo* texture = @@ -2426,7 +2439,8 @@ bool GLES2DecoderImpl::SetParent(GLES2Decoder* new_parent, TextureManager::TextureInfo* info = new_parent_impl->CreateTextureInfo(new_parent_texture_id, service_id); info->SetNotOwned(); - new_parent_impl->texture_manager()->SetInfoTarget(info, GL_TEXTURE_2D); + new_parent_impl->texture_manager()->SetInfoTarget(feature_info_, + info, GL_TEXTURE_2D); parent_ = new_parent_impl->AsWeakPtr(); @@ -2865,8 +2879,13 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { "glBindTexture: texture bound to more than 1 target."); return; } + if (info->IsStreamTexture() && target != GL_TEXTURE_EXTERNAL_OES) { + SetGLError(GL_INVALID_OPERATION, + "glBindTexture: illegal target for stream texture."); + return; + } if (info->target() == 0) { - texture_manager()->SetInfoTarget(info, target); + texture_manager()->SetInfoTarget(feature_info_, info, target); } glBindTexture(target, info->service_id()); TextureUnit& unit = texture_units_[active_texture_unit_]; @@ -2880,6 +2899,13 @@ void GLES2DecoderImpl::DoBindTexture(GLenum target, GLuint client_id) { break; case GL_TEXTURE_EXTERNAL_OES: unit.bound_texture_external_oes = info; + if (info->IsStreamTexture()) { + DCHECK(stream_texture_manager_); + StreamTexture* stream_tex = + stream_texture_manager_->LookupStreamTexture(info->service_id()); + if (stream_tex) + stream_tex->Update(); + } break; default: NOTREACHED(); // Validation should prevent us getting here. @@ -6885,6 +6911,84 @@ bool GLES2DecoderImpl::WasContextLost() { return false; } +error::Error GLES2DecoderImpl::HandleCreateStreamTextureCHROMIUM( + uint32 immediate_data_size, + const gles2::CreateStreamTextureCHROMIUM& c) { + if (!feature_info_->feature_flags().chromium_stream_texture) { + SetGLError(GL_INVALID_OPERATION, + "glOpenStreamTextureCHROMIUM: " + "not supported."); + return error::kNoError; + } + + uint32 client_id = c.client_id; + typedef gles2::CreateStreamTextureCHROMIUM::Result Result; + Result* result = GetSharedMemoryAs<Result*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result)); + + *result = GL_ZERO; + TextureManager::TextureInfo* info = + texture_manager()->GetTextureInfo(client_id); + if (!info) { + SetGLError(GL_INVALID_VALUE, + "glCreateStreamTextureCHROMIUM: " + "bad texture id."); + return error::kNoError; + } + + if (info->IsStreamTexture()) { + SetGLError(GL_INVALID_OPERATION, + "glCreateStreamTextureCHROMIUM: " + "is already a stream texture."); + return error::kNoError; + } + + if (info->target() && info->target() != GL_TEXTURE_EXTERNAL_OES) { + SetGLError(GL_INVALID_OPERATION, + "glCreateStreamTextureCHROMIUM: " + "is already bound to incompatible target."); + return error::kNoError; + } + + if (!stream_texture_manager_) + return error::kInvalidArguments; + + GLuint object_id = stream_texture_manager_->CreateStreamTexture( + info->service_id(), client_id); + + if (object_id) { + info->SetStreamTexture(true); + } else { + SetGLError(GL_OUT_OF_MEMORY, + "glCreateStreamTextureCHROMIUM: " + "failed to create platform texture."); + } + + *result = object_id; + return error::kNoError; +} + +error::Error GLES2DecoderImpl::HandleDestroyStreamTextureCHROMIUM( + uint32 immediate_data_size, + const gles2::DestroyStreamTextureCHROMIUM& c) { + GLuint client_id = c.texture; + TextureManager::TextureInfo* info = + texture_manager()->GetTextureInfo(client_id); + if (info && info->IsStreamTexture()) { + if (!stream_texture_manager_) + return error::kInvalidArguments; + + stream_texture_manager_->DestroyStreamTexture(info->service_id()); + info->SetStreamTexture(false); + texture_manager()->SetInfoTarget(feature_info_, info, 0); + } else { + SetGLError(GL_INVALID_VALUE, + "glDestroyStreamTextureCHROMIUM: bad texture id."); + } + + return error::kNoError; +} + // 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 // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index 00fff76..118c27d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -22,6 +22,7 @@ class GLSurface; namespace gpu { +class StreamTextureManager; class SurfaceManager; namespace gles2 { @@ -111,6 +112,8 @@ class GLES2Decoder : public CommonDecoder { virtual void SetSwapBuffersCallback(Callback0::Type* callback) = 0; #endif + virtual void SetStreamTextureManager(StreamTextureManager* manager) = 0; + // Get the service texture ID corresponding to a client texture ID. // If no such record is found then return false. virtual bool GetServiceTextureId(uint32 client_texture_id, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 2fb68fe..680cc28 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2572,14 +2572,6 @@ error::Error GLES2DecoderImpl::HandlePlaceholder447CHROMIUM( uint32 immediate_data_size, const gles2::Placeholder447CHROMIUM& c) { return error::kUnknownCommand; } -error::Error GLES2DecoderImpl::HandlePlaceholder451CHROMIUM( - uint32 immediate_data_size, const gles2::Placeholder451CHROMIUM& c) { - return error::kUnknownCommand; -} -error::Error GLES2DecoderImpl::HandlePlaceholder452CHROMIUM( - uint32 immediate_data_size, const gles2::Placeholder452CHROMIUM& c) { - return error::kUnknownCommand; -} error::Error GLES2DecoderImpl::HandlePlaceholder453CHROMIUM( uint32 immediate_data_size, const gles2::Placeholder453CHROMIUM& c) { return error::kUnknownCommand; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 8b3ab80..6eb313d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -20,6 +20,7 @@ class GLSurface; } namespace gpu { +class StreamTextureManager; namespace gles2 { @@ -47,6 +48,7 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD0(GetContextGroup, ContextGroup*()); MOCK_METHOD1(SetResizeCallback, void(Callback1<gfx::Size>::Type*)); MOCK_METHOD1(SetSwapBuffersCallback, void(Callback0::Type*)); + MOCK_METHOD1(SetStreamTextureManager, void(StreamTextureManager*)); MOCK_METHOD3(DoCommand, error::Error(unsigned int command, unsigned int arg_count, const void* cmd_data)); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc index c2c9e6b..c56fcbf 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc @@ -12,6 +12,8 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/context_group.h" +#include "gpu/command_buffer/service/stream_texture_mock.h" +#include "gpu/command_buffer/service/stream_texture_manager_mock.h" #include "gpu/command_buffer/service/program_manager.h" #include "gpu/command_buffer/service/test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -4595,6 +4597,249 @@ TEST_F(GLES2DecoderManualInitTest, BindGeneratesResourceFalse) { EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); } +TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUM) { + const GLuint kObjectId = 123; + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + StrictMock<MockStreamTextureManager> manager; + decoder_->SetStreamTextureManager(&manager); + + EXPECT_CALL(manager, CreateStreamTexture(kServiceTextureId, + client_texture_id_)) + .WillOnce(Return(kObjectId)) + .RetiresOnSaturation(); + + CreateStreamTextureCHROMIUM cmd; + CreateStreamTextureCHROMIUM::Result* result = + static_cast<CreateStreamTextureCHROMIUM::Result*>(shared_memory_address_); + cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(kObjectId, *result); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); + EXPECT_TRUE(info != NULL); + EXPECT_TRUE(info->IsStreamTexture()); +} + +TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMBadId) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + CreateStreamTextureCHROMIUM cmd; + CreateStreamTextureCHROMIUM::Result* result = + static_cast<CreateStreamTextureCHROMIUM::Result*>(shared_memory_address_); + cmd.Init(kNewClientId, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(static_cast<GLuint>(GL_ZERO), *result); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMAlreadyBound) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId); + + CreateStreamTextureCHROMIUM cmd; + CreateStreamTextureCHROMIUM::Result* result = + static_cast<CreateStreamTextureCHROMIUM::Result*>(shared_memory_address_); + cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(static_cast<GLuint>(GL_ZERO), *result); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, CreateStreamTextureCHROMIUMAlreadySet) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); + info->SetStreamTexture(true); + + CreateStreamTextureCHROMIUM cmd; + cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUM) { + InitDecoder( + "GL_CHROMIUM_stream_texture GL_OES_EGL_image_external", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + StrictMock<MockStreamTextureManager> manager; + StrictMock<MockStreamTexture> texture; + decoder_->SetStreamTextureManager(&manager); + + TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); + info->SetStreamTexture(true); + + EXPECT_CALL(*gl_, BindTexture(GL_TEXTURE_EXTERNAL_OES, kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(manager, LookupStreamTexture(kServiceTextureId)) + .WillOnce(Return(&texture)) + .RetiresOnSaturation(); + EXPECT_CALL(texture, Update()) + .Times(1) + .RetiresOnSaturation(); + + BindTexture cmd; + cmd.Init(GL_TEXTURE_EXTERNAL_OES, client_texture_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, BindStreamTextureCHROMIUMInvalid) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); + info->SetStreamTexture(true); + + BindTexture cmd; + cmd.Init(GL_TEXTURE_2D, client_texture_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); + + BindTexture cmd2; + cmd2.Init(GL_TEXTURE_CUBE_MAP, client_texture_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd2)); + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUM) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + StrictMock<MockStreamTextureManager> manager; + decoder_->SetStreamTextureManager(&manager); + + TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); + info->SetStreamTexture(true); + + EXPECT_CALL(manager, DestroyStreamTexture(kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); + + DestroyStreamTextureCHROMIUM cmd; + cmd.Init(client_texture_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_FALSE(info->IsStreamTexture()); + EXPECT_EQ(0U, info->target()); +} + +TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUMInvalid) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); + info->SetStreamTexture(false); + + DestroyStreamTextureCHROMIUM cmd; + cmd.Init(client_texture_id_); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, DestroyStreamTextureCHROMIUMBadId) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + DestroyStreamTextureCHROMIUM cmd; + cmd.Init(GL_ZERO); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); +} + +TEST_F(GLES2DecoderManualInitTest, StreamTextureCHROMIUMNullMgr) { + InitDecoder( + "GL_CHROMIUM_stream_texture", // extensions + false, // has alpha + false, // has depth + false, // has stencil + false, // request alpha + false, // request depth + false, // request stencil + true); // bind generates resource + + CreateStreamTextureCHROMIUM cmd; + cmd.Init(client_texture_id_, shared_memory_id_, shared_memory_offset_); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd)); + GetGLError(); // ignore internal error + + TextureManager::TextureInfo* info = GetTextureInfo(client_texture_id_); + info->SetStreamTexture(true); + + DestroyStreamTextureCHROMIUM cmd2; + cmd2.Init(client_texture_id_); + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd2)); + GetGLError(); // ignore internal error +} + // TODO(gman): Complete this test. // TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) { // } 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 ce9cc45..70eae81 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,5 +10,9 @@ #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): CreateStreamTextureCHROMIUM + +// TODO(gman): DestroyStreamTextureCHROMIUM + #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ diff --git a/gpu/command_buffer/service/stream_texture.h b/gpu/command_buffer/service/stream_texture.h new file mode 100644 index 0000000..7a493a5 --- /dev/null +++ b/gpu/command_buffer/service/stream_texture.h @@ -0,0 +1,29 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_H_ +#pragma once + +#include "base/basictypes.h" + +namespace gpu { + +class StreamTexture { + public: + StreamTexture() { + } + + virtual ~StreamTexture() { + } + + virtual void Update() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(StreamTexture); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_H_ diff --git a/gpu/command_buffer/service/stream_texture_manager.h b/gpu/command_buffer/service/stream_texture_manager.h new file mode 100644 index 0000000..b4f0a53 --- /dev/null +++ b/gpu/command_buffer/service/stream_texture_manager.h @@ -0,0 +1,38 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MANAGER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MANAGER_H_ + +#include "base/basictypes.h" +#include "gpu/command_buffer/service/gl_utils.h" + +namespace gpu { + +class StreamTexture; + +// Interface used by the cmd decoder to create and lookup stream textures. +class StreamTextureManager { + public: + StreamTextureManager() { + } + + virtual ~StreamTextureManager() { + } + + // Returns an identifier for the object, or NULL if not successful. + virtual GLuint CreateStreamTexture(uint32 service_id, + uint32 client_id) = 0; + + virtual void DestroyStreamTexture(uint32 service_id) = 0; + + virtual StreamTexture* LookupStreamTexture(uint32 service_id) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(StreamTextureManager); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MANAGER_H_ diff --git a/gpu/command_buffer/service/stream_texture_manager_mock.cc b/gpu/command_buffer/service/stream_texture_manager_mock.cc new file mode 100644 index 0000000..75268b8 --- /dev/null +++ b/gpu/command_buffer/service/stream_texture_manager_mock.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2011 The Chromium 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 "gpu/command_buffer/service/stream_texture_manager_mock.h" + +namespace gpu { + +MockStreamTextureManager::MockStreamTextureManager() { +} + +MockStreamTextureManager::~MockStreamTextureManager() { +} + +} // namespace gpu diff --git a/gpu/command_buffer/service/stream_texture_manager_mock.h b/gpu/command_buffer/service/stream_texture_manager_mock.h new file mode 100644 index 0000000..ac145ec --- /dev/null +++ b/gpu/command_buffer/service/stream_texture_manager_mock.h @@ -0,0 +1,32 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MANAGER_MOCK_H_ +#define GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MANAGER_MOCK_H_ + +#include "base/basictypes.h" +#include "gpu/command_buffer/service/stream_texture_manager.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu { + +class StreamTexture; + +class MockStreamTextureManager : public StreamTextureManager { + public: + MockStreamTextureManager(); + virtual ~MockStreamTextureManager(); + + MOCK_METHOD2(CreateStreamTexture, GLuint(uint32 service_id, + uint32 client_id)); + MOCK_METHOD1(DestroyStreamTexture, void(uint32 service_id)); + MOCK_METHOD1(LookupStreamTexture, StreamTexture*(uint32 service_id)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockStreamTextureManager); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MANAGER_MOCK_H_ diff --git a/gpu/command_buffer/service/stream_texture_mock.cc b/gpu/command_buffer/service/stream_texture_mock.cc new file mode 100644 index 0000000..742a4f7 --- /dev/null +++ b/gpu/command_buffer/service/stream_texture_mock.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2011 The Chromium 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 "gpu/command_buffer/service/stream_texture_mock.h" + +namespace gpu { + +MockStreamTexture::MockStreamTexture() { +} + +MockStreamTexture::~MockStreamTexture() { +} + +} // namespace gpu diff --git a/gpu/command_buffer/service/stream_texture_mock.h b/gpu/command_buffer/service/stream_texture_mock.h new file mode 100644 index 0000000..cc363ff --- /dev/null +++ b/gpu/command_buffer/service/stream_texture_mock.h @@ -0,0 +1,28 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MOCK_H_ +#define GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MOCK_H_ +#pragma once + +#include "base/memory/ref_counted.h" +#include "gpu/command_buffer/service/stream_texture.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace gpu { + +class MockStreamTexture : public StreamTexture { + public: + MockStreamTexture(); + virtual ~MockStreamTexture(); + + MOCK_METHOD0(Update, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockStreamTexture); +}; + +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_SERVICE_STREAM_TEXTURE_MOCK_H_ diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index 134308d..329a1f8 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -441,11 +441,11 @@ bool TextureManager::Initialize(const FeatureInfo* feature_info) { FeatureInfo temp_feature_info; default_texture_2d_ = TextureInfo::Ref(new TextureInfo(ids[1])); - SetInfoTarget(default_texture_2d_, GL_TEXTURE_2D); + SetInfoTarget(feature_info, default_texture_2d_, GL_TEXTURE_2D); default_texture_2d_->SetLevelInfo(&temp_feature_info, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); default_texture_cube_map_ = TextureInfo::Ref(new TextureInfo(ids[3])); - SetInfoTarget(default_texture_cube_map_, GL_TEXTURE_CUBE_MAP); + SetInfoTarget(feature_info, default_texture_cube_map_, GL_TEXTURE_CUBE_MAP); for (int ii = 0; ii < GLES2Util::kNumFaces; ++ii) { default_texture_cube_map_->SetLevelInfo( &temp_feature_info, GLES2Util::IndexToGLFaceTarget(ii), @@ -461,7 +461,9 @@ bool TextureManager::Initialize(const FeatureInfo* feature_info) { glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0); default_texture_external_oes_ = TextureInfo::Ref( new TextureInfo(external_ids[0])); - SetInfoTarget(default_texture_external_oes_, GL_TEXTURE_EXTERNAL_OES); + SetInfoTarget(feature_info, + default_texture_external_oes_, + GL_TEXTURE_EXTERNAL_OES); default_texture_external_oes_->SetLevelInfo( &temp_feature_info, GL_TEXTURE_EXTERNAL_OES, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); @@ -495,6 +497,19 @@ bool TextureManager::ValidForTarget( (target != GL_TEXTURE_2D || (depth == 1)); } +void TextureManager::SetInfoTarget( + const FeatureInfo* feature_info, + TextureInfo* info, GLenum target) { + DCHECK(info); + if (!info->CanRender(feature_info)) { + --num_unrenderable_textures_; + } + info->SetTarget(target, MaxLevelsForTarget(target)); + if (!info->CanRender(feature_info)) { + ++num_unrenderable_textures_; + } +} + void TextureManager::SetLevelInfo( const FeatureInfo* feature_info, TextureManager::TextureInfo* info, diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index b4e9626..dbb2218 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -43,7 +43,8 @@ class TextureManager { npot_(false), has_been_bound_(false), framebuffer_attachment_count_(0), - owned_(true) { + owned_(true), + stream_texture_(false) { } GLenum min_filter() const { @@ -66,6 +67,10 @@ class TextureManager { // See section 3.8.2 of the GLES2 spec. bool CanRender(const FeatureInfo* feature_info) const; + bool CanRenderTo() const { + return !stream_texture_ && target_ != GL_TEXTURE_EXTERNAL_OES; + } + // The service side OpenGL id of the texture. GLuint service_id() const { return service_id_; @@ -145,6 +150,14 @@ class TextureManager { --framebuffer_attachment_count_; } + void SetStreamTexture(bool stream_texture) { + stream_texture_ = stream_texture; + } + + int IsStreamTexture() { + return stream_texture_; + } + private: friend class TextureManager; friend class base::RefCounted<TextureInfo>; @@ -254,6 +267,9 @@ class TextureManager { // it. bool owned_; + // Whether this is a special streaming texture. + bool stream_texture_; + DISALLOW_COPY_AND_ASSIGN(TextureInfo); }; @@ -300,10 +316,10 @@ class TextureManager { // Parameters: // target: GL_TEXTURE_2D or GL_TEXTURE_CUBE_MAP // max_levels: The maximum levels this type of target can have. - void SetInfoTarget(TextureInfo* info, GLenum target) { - DCHECK(info); - info->SetTarget(target, MaxLevelsForTarget(target)); - } + void SetInfoTarget( + const FeatureInfo* feature_info, + TextureInfo* info, + GLenum target); // Set the info for a particular level in a TexureInfo. void SetLevelInfo( diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index cf33e72..38d1969 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -338,7 +338,7 @@ TEST_F(TextureInfoTest, Basic) { } TEST_F(TextureInfoTest, POT2D) { - manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info_->target()); // Check Setting level 0 to POT manager_.SetLevelInfo(&feature_info_, info_, @@ -383,7 +383,7 @@ TEST_F(TextureInfoTest, POT2D) { } TEST_F(TextureInfoTest, UnusedMips) { - manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info_->target()); // Set level zero to large size. manager_.SetLevelInfo(&feature_info_, info_, @@ -411,7 +411,7 @@ TEST_F(TextureInfoTest, UnusedMips) { } TEST_F(TextureInfoTest, NPOT2D) { - manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info_->target()); // Check Setting level 0 to NPOT manager_.SetLevelInfo(&feature_info_, info_, @@ -452,7 +452,7 @@ TEST_F(TextureInfoTest, NPOT2DNPOTOK) { TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); ASSERT_TRUE(info_ != NULL); - manager.SetInfoTarget(info, GL_TEXTURE_2D); + manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); // Check Setting level 0 to NPOT manager.SetLevelInfo(&feature_info, info, @@ -470,7 +470,7 @@ TEST_F(TextureInfoTest, NPOT2DNPOTOK) { } TEST_F(TextureInfoTest, POTCubeMap) { - manager_.SetInfoTarget(info_, GL_TEXTURE_CUBE_MAP); + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_CUBE_MAP); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP), info_->target()); // Check Setting level 0 each face to POT manager_.SetLevelInfo(&feature_info_, info_, @@ -555,7 +555,7 @@ TEST_F(TextureInfoTest, POTCubeMap) { } TEST_F(TextureInfoTest, GetLevelSize) { - manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D); manager_.SetLevelInfo(&feature_info_, info_, GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); GLsizei width = -1; @@ -571,7 +571,7 @@ TEST_F(TextureInfoTest, GetLevelSize) { } TEST_F(TextureInfoTest, GetLevelType) { - manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D); manager_.SetLevelInfo(&feature_info_, info_, GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); GLenum type = -1; @@ -587,7 +587,7 @@ TEST_F(TextureInfoTest, GetLevelType) { } TEST_F(TextureInfoTest, ValidForTexture) { - manager_.SetInfoTarget(info_, GL_TEXTURE_2D); + manager_.SetInfoTarget(&feature_info_, info_, GL_TEXTURE_2D); manager_.SetLevelInfo(&feature_info_, info_, GL_TEXTURE_2D, 1, GL_RGBA, 4, 5, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE); // Check bad face. @@ -641,7 +641,7 @@ TEST_F(TextureInfoTest, FloatNotLinear) { manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); - manager.SetInfoTarget(info, GL_TEXTURE_2D); + manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); manager.SetLevelInfo(&feature_info, info, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT); @@ -663,7 +663,7 @@ TEST_F(TextureInfoTest, FloatLinear) { manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); - manager.SetInfoTarget(info, GL_TEXTURE_2D); + manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); manager.SetLevelInfo(&feature_info, info, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_FLOAT); @@ -680,7 +680,7 @@ TEST_F(TextureInfoTest, HalfFloatNotLinear) { manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); - manager.SetInfoTarget(info, GL_TEXTURE_2D); + manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); manager.SetLevelInfo(&feature_info, info, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES); @@ -702,7 +702,7 @@ TEST_F(TextureInfoTest, HalfFloatLinear) { manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); - manager.SetInfoTarget(info, GL_TEXTURE_2D); + manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_2D); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D), info->target()); manager.SetLevelInfo(&feature_info, info, GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 1, 0, GL_RGBA, GL_HALF_FLOAT_OES); @@ -719,7 +719,7 @@ TEST_F(TextureInfoTest, EGLImageExternal) { manager.CreateTextureInfo(&feature_info, kClient1Id, kService1Id); TextureManager::TextureInfo* info = manager_.GetTextureInfo(kClient1Id); ASSERT_TRUE(info != NULL); - manager.SetInfoTarget(info, GL_TEXTURE_EXTERNAL_OES); + manager.SetInfoTarget(&feature_info_, info, GL_TEXTURE_EXTERNAL_OES); EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), info->target()); EXPECT_FALSE(info->CanGenerateMipmaps(&feature_info)); manager.Destroy(false); diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index dbb7cee..399f307 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -229,6 +229,8 @@ 'command_buffer/service/shader_manager.cc', 'command_buffer/service/shader_translator.h', 'command_buffer/service/shader_translator.cc', + 'command_buffer/service/stream_texture.h', + 'command_buffer/service/stream_texture_manager.h', 'command_buffer/service/texture_manager.h', 'command_buffer/service/texture_manager.cc', 'command_buffer/service/vertex_attrib_manager.h', @@ -305,6 +307,10 @@ 'command_buffer/service/renderbuffer_manager_unittest.cc', 'command_buffer/service/shader_manager_unittest.cc', 'command_buffer/service/shader_translator_unittest.cc', + 'command_buffer/service/stream_texture_mock.cc', + 'command_buffer/service/stream_texture_mock.h', + 'command_buffer/service/stream_texture_manager_mock.cc', + 'command_buffer/service/stream_texture_manager_mock.h', 'command_buffer/service/test_helper.cc', 'command_buffer/service/test_helper.h', 'command_buffer/service/texture_manager_unittest.cc', |