Home | History | Annotate | Download | only in service
      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