1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "gpu/command_buffer/service/stream_texture_manager_in_process_android.h" 6 7 #include "base/bind.h" 8 #include "base/callback.h" 9 #include "gpu/command_buffer/service/texture_manager.h" 10 #include "ui/gfx/size.h" 11 #include "ui/gl/android/surface_texture.h" 12 #include "ui/gl/gl_bindings.h" 13 #include "ui/gl/gl_image.h" 14 15 namespace gpu { 16 17 namespace { 18 19 // Simply wraps a SurfaceTexture reference as a GLImage. 20 class GLImageImpl : public gfx::GLImage { 21 public: 22 GLImageImpl(const scoped_refptr<gfx::SurfaceTexture>& surface_texture, 23 const base::Closure& release_callback); 24 25 // implement gfx::GLImage 26 virtual void Destroy() OVERRIDE; 27 virtual gfx::Size GetSize() OVERRIDE; 28 virtual bool BindTexImage(unsigned target) OVERRIDE; 29 virtual void ReleaseTexImage(unsigned target) OVERRIDE; 30 virtual void WillUseTexImage() OVERRIDE; 31 virtual void DidUseTexImage() OVERRIDE {} 32 virtual void WillModifyTexImage() OVERRIDE {} 33 virtual void DidModifyTexImage() OVERRIDE {} 34 35 private: 36 virtual ~GLImageImpl(); 37 38 scoped_refptr<gfx::SurfaceTexture> surface_texture_; 39 base::Closure release_callback_; 40 41 DISALLOW_COPY_AND_ASSIGN(GLImageImpl); 42 }; 43 44 GLImageImpl::GLImageImpl( 45 const scoped_refptr<gfx::SurfaceTexture>& surface_texture, 46 const base::Closure& release_callback) 47 : surface_texture_(surface_texture), release_callback_(release_callback) {} 48 49 GLImageImpl::~GLImageImpl() { 50 release_callback_.Run(); 51 } 52 53 void GLImageImpl::Destroy() { 54 NOTREACHED(); 55 } 56 57 void GLImageImpl::WillUseTexImage() { 58 surface_texture_->UpdateTexImage(); 59 } 60 61 bool GLImageImpl::BindTexImage(unsigned target) { 62 NOTREACHED(); 63 return false; 64 } 65 66 void GLImageImpl::ReleaseTexImage(unsigned target) { 67 NOTREACHED(); 68 } 69 70 gfx::Size GLImageImpl::GetSize() { 71 return gfx::Size(); 72 } 73 74 } // anonymous namespace 75 76 StreamTextureManagerInProcess::StreamTextureManagerInProcess() 77 : next_id_(1), weak_factory_(this) {} 78 79 StreamTextureManagerInProcess::~StreamTextureManagerInProcess() { 80 if (!textures_.empty()) { 81 LOG(WARNING) << "Undestroyed surface textures while tearing down " 82 "StreamTextureManager."; 83 } 84 } 85 86 GLuint StreamTextureManagerInProcess::CreateStreamTexture( 87 uint32 client_texture_id, 88 gles2::TextureManager* texture_manager) { 89 CalledOnValidThread(); 90 91 gles2::TextureRef* texture = texture_manager->GetTexture(client_texture_id); 92 93 if (!texture || (texture->texture()->target() && 94 texture->texture()->target() != GL_TEXTURE_EXTERNAL_OES)) { 95 return 0; 96 } 97 98 scoped_refptr<gfx::SurfaceTexture> surface_texture( 99 gfx::SurfaceTexture::Create(texture->service_id())); 100 101 uint32 stream_id = next_id_++; 102 base::Closure release_callback = 103 base::Bind(&StreamTextureManagerInProcess::OnReleaseStreamTexture, 104 weak_factory_.GetWeakPtr(), stream_id); 105 scoped_refptr<gfx::GLImage> gl_image(new GLImageImpl(surface_texture, 106 release_callback)); 107 108 gfx::Size size = gl_image->GetSize(); 109 texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES); 110 texture_manager->SetLevelInfo(texture, 111 GL_TEXTURE_EXTERNAL_OES, 112 0, 113 GL_RGBA, 114 size.width(), 115 size.height(), 116 1, 117 0, 118 GL_RGBA, 119 GL_UNSIGNED_BYTE, 120 true); 121 texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image); 122 123 { 124 base::AutoLock lock(map_lock_); 125 textures_[stream_id] = surface_texture; 126 } 127 128 if (next_id_ == 0) 129 next_id_++; 130 131 return stream_id; 132 } 133 134 void StreamTextureManagerInProcess::OnReleaseStreamTexture(uint32 stream_id) { 135 CalledOnValidThread(); 136 base::AutoLock lock(map_lock_); 137 textures_.erase(stream_id); 138 } 139 140 // This can get called from any thread. 141 scoped_refptr<gfx::SurfaceTexture> 142 StreamTextureManagerInProcess::GetSurfaceTexture(uint32 stream_id) { 143 base::AutoLock lock(map_lock_); 144 TextureMap::const_iterator it = textures_.find(stream_id); 145 if (it != textures_.end()) 146 return it->second; 147 148 return NULL; 149 } 150 151 } // namespace gpu 152