diff options
author | sheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-26 08:59:00 +0000 |
---|---|---|
committer | sheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-26 08:59:00 +0000 |
commit | 3ecc1053b09adb0f0c32847e8901285339b34074 (patch) | |
tree | ccd73be429c31aac261fc95f93490261f46efb33 /gpu | |
parent | 50736a1f2b006d294baaf1f125bb453719b58c88 (diff) | |
download | chromium_src-3ecc1053b09adb0f0c32847e8901285339b34074.zip chromium_src-3ecc1053b09adb0f0c32847e8901285339b34074.tar.gz chromium_src-3ecc1053b09adb0f0c32847e8901285339b34074.tar.bz2 |
Allow rendering from non-stream GL_TEXTURE_EXTERNAL_OES
Towards support for compositing from GL_TEXTURE_EXTERNAL_OES textures exported
by other drivers into the GL stack.
BUG=167417
TEST=local build, unittests, run on CrOS snow
Review URL: https://codereview.chromium.org/24152009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225410 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 47 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.cc | 48 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager.h | 6 | ||||
-rw-r--r-- | gpu/command_buffer/service/texture_manager_unittest.cc | 24 |
4 files changed, 75 insertions, 50 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index b5ba2dc..e42a44c 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -9646,34 +9646,17 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( if (dest_texture->target() != GL_TEXTURE_2D || (source_texture->target() != GL_TEXTURE_2D && source_texture->target() != GL_TEXTURE_EXTERNAL_OES)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, - "glCopyTextureCHROMIUM", "invalid texture target binding"); + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, + "glCopyTextureCHROMIUM", + "invalid texture target binding"); return; } int source_width, source_height, dest_width, dest_height; - if (source_texture->target() == GL_TEXTURE_2D) { - if (!source_texture->GetLevelSize(GL_TEXTURE_2D, 0, &source_width, - &source_height)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, - "glCopyTextureChromium", "source texture has no level 0"); - return; - } - - // Check that this type of texture is allowed. - if (!texture_manager()->ValidForTarget(GL_TEXTURE_2D, level, source_width, - source_height, 1)) { - LOCAL_SET_GL_ERROR( - GL_INVALID_VALUE, - "glCopyTextureCHROMIUM", "Bad dimensions"); - return; - } - } - - if (source_texture->target() == GL_TEXTURE_EXTERNAL_OES) { + if (source_texture->IsStreamTexture()) { + DCHECK_EQ(source_texture->target(), + static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES)); DCHECK(stream_texture_manager()); StreamTexture* stream_tex = stream_texture_manager()->LookupStreamTexture( @@ -9693,6 +9676,22 @@ void GLES2DecoderImpl::DoCopyTextureCHROMIUM( "glCopyTextureChromium", "invalid streamtexture size"); return; } + } else { + if (!source_texture->GetLevelSize( + source_texture->target(), 0, &source_width, &source_height)) { + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, + "glCopyTextureChromium", + "source texture has no level 0"); + return; + } + + // Check that this type of texture is allowed. + if (!texture_manager()->ValidForTarget( + source_texture->target(), level, source_width, source_height, 1)) { + LOCAL_SET_GL_ERROR( + GL_INVALID_VALUE, "glCopyTextureCHROMIUM", "Bad dimensions"); + return; + } } // Defer initializing the CopyTextureCHROMIUMResourceManager until it is @@ -9828,7 +9827,7 @@ void GLES2DecoderImpl::DoTexStorage2DEXT( GLsizei height) { TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoTexStorage2DEXT"); if (!texture_manager()->ValidForTarget(target, 0, width, height, 1) || - TextureManager::ComputeMipMapCount(width, height, 1) < levels) { + TextureManager::ComputeMipMapCount(target, width, height, 1) < levels) { LOCAL_SET_GL_ERROR( GL_INVALID_VALUE, "glTexStorage2DEXT", "dimensions out of range"); return; diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc index deb8c8e..9684493 100644 --- a/gpu/command_buffer/service/texture_manager.cc +++ b/gpu/command_buffer/service/texture_manager.cc @@ -198,11 +198,7 @@ Texture::CanRenderCondition Texture::GetCanRenderCondition() const { if (target_ == 0) return CAN_RENDER_ALWAYS; - if (target_ == GL_TEXTURE_EXTERNAL_OES) { - if (!IsStreamTexture()) { - return CAN_RENDER_NEVER; - } - } else { + if (target_ != GL_TEXTURE_EXTERNAL_OES) { if (level_infos_.empty()) { return CAN_RENDER_NEVER; } @@ -294,7 +290,8 @@ bool Texture::MarkMipmapsGenerated( GLsizei depth = info1.depth; GLenum target = target_ == GL_TEXTURE_2D ? GL_TEXTURE_2D : FaceIndexToGLTarget(ii); - int num_mips = TextureManager::ComputeMipMapCount(width, height, depth); + int num_mips = + TextureManager::ComputeMipMapCount(target_, width, height, depth); for (int level = 1; level < num_mips; ++level) { width = std::max(1, width >> 1); height = std::max(1, height >> 1); @@ -390,7 +387,7 @@ void Texture::UpdateCleared() { const Texture::LevelInfo& first_face = level_infos_[0][0]; int levels_needed = TextureManager::ComputeMipMapCount( - first_face.width, first_face.height, first_face.depth); + target_, first_face.width, first_face.height, first_face.depth); bool cleared = true; for (size_t ii = 0; ii < level_infos_.size(); ++ii) { for (GLint jj = 0; jj < levels_needed; ++jj) { @@ -643,7 +640,7 @@ void Texture::Update(const FeatureInfo* feature_info) { // Update texture_complete and cube_complete status. const Texture::LevelInfo& first_face = level_infos_[0][0]; int levels_needed = TextureManager::ComputeMipMapCount( - first_face.width, first_face.height, first_face.depth); + target_, first_face.width, first_face.height, first_face.depth); texture_complete_ = max_level_set_ >= (levels_needed - 1) && max_level_set_ >= 0; cube_complete_ = (level_infos_.size() == 6) && @@ -708,7 +705,7 @@ bool Texture::ClearRenderableLevels(GLES2Decoder* decoder) { const Texture::LevelInfo& first_face = level_infos_[0][0]; int levels_needed = TextureManager::ComputeMipMapCount( - first_face.width, first_face.height, first_face.depth); + target_, first_face.width, first_face.height, first_face.depth); for (size_t ii = 0; ii < level_infos_.size(); ++ii) { for (GLint jj = 0; jj < levels_needed; ++jj) { @@ -824,13 +821,12 @@ TextureRef::~TextureRef() { manager_ = NULL; } -TextureManager::TextureManager( - MemoryTracker* memory_tracker, - FeatureInfo* feature_info, - GLint max_texture_size, - GLint max_cube_map_texture_size) - : memory_tracker_managed_( - new MemoryTypeTracker(memory_tracker, MemoryTracker::kManaged)), +TextureManager::TextureManager(MemoryTracker* memory_tracker, + FeatureInfo* feature_info, + GLint max_texture_size, + GLint max_cube_map_texture_size) + : memory_tracker_managed_(new MemoryTypeTracker(memory_tracker, + MemoryTracker::kManaged)), memory_tracker_unmanaged_( new MemoryTypeTracker(memory_tracker, MemoryTracker::kUnmanaged)), feature_info_(feature_info), @@ -838,10 +834,12 @@ TextureManager::TextureManager( stream_texture_manager_(NULL), max_texture_size_(max_texture_size), max_cube_map_texture_size_(max_cube_map_texture_size), - max_levels_(ComputeMipMapCount(max_texture_size, + max_levels_(ComputeMipMapCount(GL_TEXTURE_2D, + max_texture_size, max_texture_size, max_texture_size)), - max_cube_map_levels_(ComputeMipMapCount(max_cube_map_texture_size, + max_cube_map_levels_(ComputeMipMapCount(GL_TEXTURE_CUBE_MAP, + max_cube_map_texture_size, max_cube_map_texture_size, max_cube_map_texture_size)), num_unrenderable_textures_(0), @@ -1184,9 +1182,17 @@ Texture* TextureManager::GetTextureForServiceId(GLuint service_id) const { return NULL; } -GLsizei TextureManager::ComputeMipMapCount( - GLsizei width, GLsizei height, GLsizei depth) { - return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth)); +GLsizei TextureManager::ComputeMipMapCount(GLenum target, + GLsizei width, + GLsizei height, + GLsizei depth) { + switch (target) { + case GL_TEXTURE_EXTERNAL_OES: + return 1; + default: + return 1 + + base::bits::Log2Floor(std::max(std::max(width, height), depth)); + } } void TextureManager::SetLevelImage( diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h index db47004..0a6e776 100644 --- a/gpu/command_buffer/service/texture_manager.h +++ b/gpu/command_buffer/service/texture_manager.h @@ -528,8 +528,10 @@ class GPU_EXPORT TextureManager { } // Returns the maxium number of levels a texture of the given size can have. - static GLsizei ComputeMipMapCount( - GLsizei width, GLsizei height, GLsizei depth); + static GLsizei ComputeMipMapCount(GLenum target, + GLsizei width, + GLsizei height, + GLsizei depth); // Checks if a dimensions are valid for a given target. bool ValidForTarget( diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc index 483aaf2..2f5f036 100644 --- a/gpu/command_buffer/service/texture_manager_unittest.cc +++ b/gpu/command_buffer/service/texture_manager_unittest.cc @@ -466,11 +466,9 @@ TEST_F(TextureTest, SetTargetTextureExternalOES) { EXPECT_FALSE(TextureTestHelper::IsCubeComplete(texture)); EXPECT_FALSE(manager_->CanGenerateMipmaps(texture_ref_.get())); EXPECT_TRUE(TextureTestHelper::IsNPOT(texture)); - EXPECT_FALSE(manager_->CanRender(texture_ref_.get())); + EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); EXPECT_TRUE(texture->SafeToRenderFrom()); EXPECT_TRUE(texture->IsImmutable()); - manager_->SetStreamTexture(texture_ref_.get(), true); - EXPECT_TRUE(manager_->CanRender(texture_ref_.get())); } TEST_F(TextureTest, ZeroSizeCanNotRender) { @@ -2002,6 +2000,26 @@ TEST_F(ProduceConsumeTextureTest, ProduceConsumeClearRectangle) { decoder_.get(), restored_texture.get(), GL_TEXTURE_RECTANGLE_ARB, 0)); } +TEST_F(ProduceConsumeTextureTest, ProduceConsumeExternal) { + manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES); + Texture* texture = texture_ref_->texture(); + EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), texture->target()); + LevelInfo level0( + GL_TEXTURE_EXTERNAL_OES, GL_RGBA, 1, 1, 1, 0, GL_UNSIGNED_BYTE, false); + SetLevelInfo(texture_ref_.get(), 0, level0); + EXPECT_TRUE(TextureTestHelper::IsTextureComplete(texture)); + Texture* produced_texture = Produce(texture_ref_.get()); + EXPECT_EQ(produced_texture, texture); + + GLuint client_id = texture2_->client_id(); + manager_->RemoveTexture(client_id); + Consume(client_id, produced_texture); + scoped_refptr<TextureRef> restored_texture = manager_->GetTexture(client_id); + EXPECT_EQ(produced_texture, restored_texture->texture()); + EXPECT_EQ(level0, + GetLevelInfo(restored_texture.get(), GL_TEXTURE_EXTERNAL_OES, 0)); +} + TEST_F(ProduceConsumeTextureTest, ProduceConsumeStreamTexture) { manager_->SetTarget(texture_ref_.get(), GL_TEXTURE_EXTERNAL_OES); Texture* texture = texture_ref_->texture(); |