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(bool have_context) OVERRIDE; 27 virtual gfx::Size GetSize() OVERRIDE; 28 virtual bool BindTexImage(unsigned target) OVERRIDE; 29 virtual void ReleaseTexImage(unsigned target) OVERRIDE; 30 virtual bool CopyTexImage(unsigned target) OVERRIDE; 31 virtual void WillUseTexImage() OVERRIDE; 32 virtual void DidUseTexImage() OVERRIDE {} 33 virtual void WillModifyTexImage() OVERRIDE {} 34 virtual void DidModifyTexImage() OVERRIDE {} 35 virtual bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 36 int z_order, 37 gfx::OverlayTransform transform, 38 const gfx::Rect& bounds_rect, 39 const gfx::RectF& crop_rect) OVERRIDE; 40 41 private: 42 virtual ~GLImageImpl(); 43 44 scoped_refptr<gfx::SurfaceTexture> surface_texture_; 45 base::Closure release_callback_; 46 47 DISALLOW_COPY_AND_ASSIGN(GLImageImpl); 48 }; 49 50 GLImageImpl::GLImageImpl( 51 const scoped_refptr<gfx::SurfaceTexture>& surface_texture, 52 const base::Closure& release_callback) 53 : surface_texture_(surface_texture), release_callback_(release_callback) {} 54 55 GLImageImpl::~GLImageImpl() { 56 release_callback_.Run(); 57 } 58 59 void GLImageImpl::Destroy(bool have_context) { 60 NOTREACHED(); 61 } 62 63 gfx::Size GLImageImpl::GetSize() { 64 return gfx::Size(); 65 } 66 67 bool GLImageImpl::BindTexImage(unsigned target) { 68 NOTREACHED(); 69 return false; 70 } 71 72 void GLImageImpl::ReleaseTexImage(unsigned target) { 73 NOTREACHED(); 74 } 75 76 bool GLImageImpl::CopyTexImage(unsigned target) { 77 return false; 78 } 79 80 void GLImageImpl::WillUseTexImage() { 81 surface_texture_->UpdateTexImage(); 82 } 83 84 bool GLImageImpl::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, 85 int z_order, 86 gfx::OverlayTransform transform, 87 const gfx::Rect& bounds_rect, 88 const gfx::RectF& crop_rect) { 89 NOTREACHED(); 90 return false; 91 } 92 93 } // anonymous namespace 94 95 StreamTextureManagerInProcess::StreamTextureManagerInProcess() 96 : next_id_(1), weak_factory_(this) {} 97 98 StreamTextureManagerInProcess::~StreamTextureManagerInProcess() { 99 if (!textures_.empty()) { 100 LOG(WARNING) << "Undestroyed surface textures while tearing down " 101 "StreamTextureManager."; 102 } 103 } 104 105 GLuint StreamTextureManagerInProcess::CreateStreamTexture( 106 uint32 client_texture_id, 107 gles2::TextureManager* texture_manager) { 108 CalledOnValidThread(); 109 110 gles2::TextureRef* texture = texture_manager->GetTexture(client_texture_id); 111 112 if (!texture || (texture->texture()->target() && 113 texture->texture()->target() != GL_TEXTURE_EXTERNAL_OES)) { 114 return 0; 115 } 116 117 scoped_refptr<gfx::SurfaceTexture> surface_texture( 118 gfx::SurfaceTexture::Create(texture->service_id())); 119 120 uint32 stream_id = next_id_++; 121 base::Closure release_callback = 122 base::Bind(&StreamTextureManagerInProcess::OnReleaseStreamTexture, 123 weak_factory_.GetWeakPtr(), stream_id); 124 scoped_refptr<gfx::GLImage> gl_image(new GLImageImpl(surface_texture, 125 release_callback)); 126 127 gfx::Size size = gl_image->GetSize(); 128 texture_manager->SetTarget(texture, GL_TEXTURE_EXTERNAL_OES); 129 texture_manager->SetLevelInfo(texture, 130 GL_TEXTURE_EXTERNAL_OES, 131 0, 132 GL_RGBA, 133 size.width(), 134 size.height(), 135 1, 136 0, 137 GL_RGBA, 138 GL_UNSIGNED_BYTE, 139 true); 140 texture_manager->SetLevelImage(texture, GL_TEXTURE_EXTERNAL_OES, 0, gl_image); 141 142 { 143 base::AutoLock lock(map_lock_); 144 textures_[stream_id] = surface_texture; 145 } 146 147 if (next_id_ == 0) 148 next_id_++; 149 150 return stream_id; 151 } 152 153 void StreamTextureManagerInProcess::OnReleaseStreamTexture(uint32 stream_id) { 154 CalledOnValidThread(); 155 base::AutoLock lock(map_lock_); 156 textures_.erase(stream_id); 157 } 158 159 // This can get called from any thread. 160 scoped_refptr<gfx::SurfaceTexture> 161 StreamTextureManagerInProcess::GetSurfaceTexture(uint32 stream_id) { 162 base::AutoLock lock(map_lock_); 163 TextureMap::const_iterator it = textures_.find(stream_id); 164 if (it != textures_.end()) 165 return it->second; 166 167 return NULL; 168 } 169 170 } // namespace gpu 171