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