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(¶ms.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