// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/renderer/transport_texture_service.h" #include "base/stl_util-inl.h" #include "content/common/child_process.h" #include "content/common/gpu_messages.h" #include "content/renderer/transport_texture_host.h" TransportTextureService::TransportTextureService() : channel_(NULL), next_host_id_(1) { } TransportTextureService::~TransportTextureService() { STLDeleteElements(&pending_messages_); } void TransportTextureService::OnFilterAdded(IPC::Channel* channel) { channel_ = channel; router_.reset(new MessageRouter()); // Add all pending routes. for (size_t i = 0; i < pending_routes_.size(); ++i) router_->AddRoute(pending_routes_[i].first, pending_routes_[i].second); pending_routes_.clear(); // Submit all pending messages. for (size_t i = 0; i < pending_messages_.size(); ++i) channel_->Send(pending_messages_[i]); pending_messages_.clear(); } void TransportTextureService::OnFilterRemoved() { // TODO(hclam): Implement. } void TransportTextureService::OnChannelClosing() { channel_ = NULL; } bool TransportTextureService::OnMessageReceived(const IPC::Message& msg) { switch (msg.type()) { case GpuTransportTextureHostMsg_TransportTextureCreated::ID: case GpuTransportTextureHostMsg_CreateTextures::ID: case GpuTransportTextureHostMsg_ReleaseTextures::ID: case GpuTransportTextureHostMsg_TextureUpdated::ID: if (!router_->RouteMessage(msg)) { LOG(ERROR) << "GpuTransportTextureHostMsg cannot be dispatched."; return false; } return true; default: return false; } } scoped_refptr TransportTextureService::CreateTransportTextureHost( RendererGLContext* context, int context_route_id) { #if !defined(OS_MACOSX) // TODO(hclam): Check this is on Render Thread. // Create the object and then add the route. scoped_refptr host = new TransportTextureHost( ChildProcess::current()->io_message_loop(), MessageLoop::current(), this, this, context, context_route_id, next_host_id_); // Add route in the IO thread. ChildProcess::current()->io_message_loop()->PostTask( FROM_HERE, NewRunnableMethod(this, &TransportTextureService::AddRouteInternal, next_host_id_, host)); // Increment host ID for next object. ++next_host_id_; return host; #else // TransportTextureHost has problem compiling on Mac so skip it. return NULL; #endif } void TransportTextureService::RemoveRoute(int32 host_id) { ChildProcess::current()->io_message_loop()->PostTask( FROM_HERE, NewRunnableMethod(this, &TransportTextureService::RemoveRouteInternal, host_id)); } bool TransportTextureService::Send(IPC::Message* msg) { ChildProcess::current()->io_message_loop()->PostTask( FROM_HERE, NewRunnableMethod(this, &TransportTextureService::SendInternal, msg)); return true; } void TransportTextureService::AddRouteInternal( int32 host_id, IPC::Channel::Listener* listener) { DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current()); // If router is there then just add the route, or we have to save it. if (router_.get()) router_->AddRoute(host_id, listener); else pending_routes_.push_back(std::make_pair(host_id, listener)); } void TransportTextureService::RemoveRouteInternal(int32 host_id) { DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current()); if (router_.get()) router_->RemoveRoute(host_id); } void TransportTextureService::SendInternal(IPC::Message* msg) { DCHECK_EQ(ChildProcess::current()->io_message_loop(), MessageLoop::current()); if (channel_) channel_->Send(msg); else pending_messages_.push_back(msg); }