Home | History | Annotate | Download | only in gpu
      1 // Copyright (c) 2012 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 "content/common/gpu/stream_texture_manager_android.h"
      6 
      7 #include "base/bind.h"
      8 #include "content/common/gpu/gpu_channel.h"
      9 #include "content/common/gpu/gpu_messages.h"
     10 #include "gpu/command_buffer/service/stream_texture.h"
     11 #include "ui/gfx/size.h"
     12 #include "ui/gl/android/surface_texture_bridge.h"
     13 #include "ui/gl/gl_bindings.h"
     14 
     15 namespace content {
     16 
     17 StreamTextureManagerAndroid::StreamTextureAndroid::StreamTextureAndroid(
     18     GpuChannel* channel, int service_id)
     19     : surface_texture_bridge_(new gfx::SurfaceTextureBridge(service_id)),
     20       size_(0, 0),
     21       has_updated_(false),
     22       channel_(channel) {
     23   memset(current_matrix_, 0, sizeof(current_matrix_));
     24 }
     25 
     26 StreamTextureManagerAndroid::StreamTextureAndroid::~StreamTextureAndroid() {
     27 }
     28 
     29 void StreamTextureManagerAndroid::StreamTextureAndroid::Update() {
     30   surface_texture_bridge_->UpdateTexImage();
     31   if (matrix_callback_.is_null())
     32     return;
     33 
     34   float mtx[16];
     35   surface_texture_bridge_->GetTransformMatrix(mtx);
     36 
     37   // Only query the matrix once we have bound a valid frame.
     38   if (has_updated_ && memcmp(current_matrix_, mtx, sizeof(mtx)) != 0) {
     39     memcpy(current_matrix_, mtx, sizeof(mtx));
     40 
     41     GpuStreamTextureMsg_MatrixChanged_Params params;
     42     memcpy(&params.m00, mtx, sizeof(mtx));
     43     matrix_callback_.Run(params);
     44   }
     45 }
     46 
     47 void StreamTextureManagerAndroid::StreamTextureAndroid::OnFrameAvailable(
     48     int route_id) {
     49   has_updated_ = true;
     50   channel_->Send(new GpuStreamTextureMsg_FrameAvailable(route_id));
     51 }
     52 
     53 gfx::Size StreamTextureManagerAndroid::StreamTextureAndroid::GetSize() {
     54   return size_;
     55 }
     56 
     57 StreamTextureManagerAndroid::StreamTextureManagerAndroid(
     58     GpuChannel* channel)
     59     : channel_(channel) {
     60 }
     61 
     62 StreamTextureManagerAndroid::~StreamTextureManagerAndroid() {
     63   DCHECK(textures_.size() == textures_from_service_id_.size());
     64   if (!textures_.IsEmpty())
     65     LOG(WARNING) << "Undestroyed surface textures while closing GPU channel.";
     66 }
     67 
     68 GLuint StreamTextureManagerAndroid::CreateStreamTexture(uint32 service_id,
     69                                                         uint32 client_id) {
     70   // service_id: the actual GL texture name
     71   // client_id: texture name given to the client in the renderer (unused here)
     72   // The return value here is what glCreateStreamTextureCHROMIUM() will return
     73   // to identify the stream (i.e. surface texture).
     74   StreamTextureAndroid* texture = new StreamTextureAndroid(
     75       channel_, service_id);
     76   textures_from_service_id_.AddWithID(texture, service_id);
     77   return textures_.Add(texture);
     78 }
     79 
     80 void StreamTextureManagerAndroid::DestroyStreamTexture(uint32 service_id) {
     81   gpu::StreamTexture* texture = textures_from_service_id_.Lookup(service_id);
     82   if (texture) {
     83     textures_from_service_id_.Remove(service_id);
     84 
     85     for (TextureMap::Iterator<StreamTextureAndroid> it(&textures_);
     86         !it.IsAtEnd(); it.Advance()) {
     87       if (it.GetCurrentValue() == texture) {
     88         textures_.Remove(it.GetCurrentKey());
     89         break;
     90       }
     91     }
     92   }
     93 }
     94 
     95 gpu::StreamTexture* StreamTextureManagerAndroid::LookupStreamTexture(
     96     uint32 service_id) {
     97   return textures_from_service_id_.Lookup(service_id);
     98 }
     99 
    100 void StreamTextureManagerAndroid::SendMatrixChanged(
    101     int route_id,
    102     const GpuStreamTextureMsg_MatrixChanged_Params& params) {
    103   channel_->Send(new GpuStreamTextureMsg_MatrixChanged(route_id, params));
    104 }
    105 
    106 void StreamTextureManagerAndroid::RegisterStreamTextureProxy(
    107     int32 stream_id, int32 route_id) {
    108   StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
    109   if (stream_texture) {
    110     // TODO(sievers): Post from binder thread to IO thread directly.
    111     base::Closure frame_cb = base::Bind(
    112           &StreamTextureAndroid::OnFrameAvailable,
    113           stream_texture->AsWeakPtr(),
    114           route_id);
    115     StreamTextureAndroid::MatrixChangedCB matrix_cb = base::Bind(
    116           &StreamTextureManagerAndroid::SendMatrixChanged,
    117           base::Unretained(this),
    118           route_id);
    119     stream_texture->set_matrix_changed_callback(matrix_cb);
    120     stream_texture->surface_texture_bridge()->SetFrameAvailableCallback(
    121         frame_cb);
    122   }
    123 }
    124 
    125 void StreamTextureManagerAndroid::EstablishStreamTexture(
    126     int32 stream_id, int32 primary_id, int32 secondary_id) {
    127   StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
    128   base::ProcessHandle process = channel_->renderer_pid();
    129 
    130   if (stream_texture) {
    131     SurfaceTexturePeer::GetInstance()->EstablishSurfaceTexturePeer(
    132         process,
    133         stream_texture->surface_texture_bridge(),
    134         primary_id,
    135         secondary_id);
    136   }
    137 }
    138 
    139 void StreamTextureManagerAndroid::SetStreamTextureSize(
    140     int32 stream_id, const gfx::Size& size) {
    141   StreamTextureAndroid* stream_texture = textures_.Lookup(stream_id);
    142   if (stream_texture)
    143     stream_texture->SetSize(size);
    144 }
    145 
    146 }  // namespace content
    147