// Copyright (c) 2011 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. // Transport texture is a mechanism to share a texture between renderer process // and GPU process. This is useful when a texture is used in the renderer // process but updated in the GPU process. // // BACKGROUND INFORMATION // // Renderer process uses command buffer to submit GLES2 commands to the GPU // process for execution. When using a texture in the renderer process it is // supposed to update the texture, for example by using glTexImage2D(). // // However for some cases the texture needs to be updated in the GPU process. // Objects other than command buffer in the GPU process will then need to // access the texture ID. // // This class provides the following functions that solve the problems: // 1. Textures be requested in the GPU process. The request is submitted // to renderer process and textures are created in the command buffer // context and eventually in the system context. // 2. Textures are then create and used in the renderer process. // 3. The corresponding texture ID in the GPU process can be obtained. // 4. When texture is updated in the GPU process, notification can be received // in the renderer process. // // THREAD SEMANTICS // // TransportTextureHost *must* be created on the render thread. // After that methods of this object call be called on any thread. // // GLES2 commands are executed on Render Thread. IPC messages are sent and // received on IO thread. // // USAGE // // -------------------------- // | In the renderer procss | // -------------------------- // // class TextureUpdateHandler { // public: // void OnTextureUpdate(int texture_id) { // // Do something with the texture. // } // } // // TransportTextureHost factory_host; // TextureUpdateHandler handler; // // void MyObjectInitDone() { // std::vector textures; // factory_host.GetTextures( // NewCallback(&handler, &TextureUpdateHandler::OnTextureUpdate), // &textures); // } // // void InitDone() { // InitMyObjectInGPUProcess(factory_host.GetPeerId(), // NewRunnableFunction(&MyObjectInitDone)); // } // // factory_host.Init(NewRunnableFunction(&InitDone)); // // ---------------------- // | In the GPU process | // ---------------------- // // // When the transport texture factory id is known. // TransportTexture* factory = gpu_channel->GetTransportTexture(id); // // void TextureCreateDone(vector textures) { // // Send message to renderer saying init is done. // SendInitDone(); // // UpdateTextureContent(textures[0]); // factory->TextureUpdated(textures[0]); // } // // // When init is requested from renderer. // vector textures; // // void OnInit() { // factory->CreateTextures(3, 1024, 768, TransportTexture::RGB, &textures, // NewRunnableFunction(&TextureCreateDone), // textures); // } #ifndef CONTENT_RENDERER_GPU_TRANSPORT_TEXTURE_HOST_H_ #define CONTENT_RENDERER_GPU_TRANSPORT_TEXTURE_HOST_H_ #include #include "base/basictypes.h" #include "base/callback_old.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/task.h" #include "ipc/ipc_channel.h" class MessageLoop; class RendererGLContext; class TransportTextureService; class TransportTextureHost : public base::RefCountedThreadSafe, public IPC::Channel::Listener { public: typedef Callback1::Type TextureUpdateCallback; // |io_message_loop| is where the IPC communication should happen. // |render_message_loop| is where the GLES2 commands should be exeucted. // |service| contains the route to this object. // |sender| is used to send IPC messages to GPU process. // |context| is the RendererGLContextt for generating textures. // |context_route_id| is the route ID for the GpuChannelHost. // |host_id| is the ID of this object in GpuChannelHost. TransportTextureHost(MessageLoop* io_message_loop, MessageLoop* render_message_loop, TransportTextureService* service, IPC::Message::Sender* sender, RendererGLContext* context, int32 context_route_id, int32 host_id); virtual ~TransportTextureHost(); // Initialize this object, this will cause a corresponding // TransportTexture be created in the GPU process. // |done_task| is called when initialization is completed. void Init(Task* done_task); // Destroy resources acquired by this object and in the GPU process. // // WARNING // // Call this method only after textures are not used in both the renderer // and GPU process. void Destroy(); // Get the list of textures generated through this factory. // A callback must be provided to listen to texture update events. The // callback will be called on the IO thread. // // Note that this method doesn't generate any textures, it simply return // the list of textures generated. void GetTextures(TextureUpdateCallback* callback, std::vector* textures); // Return the peer ID of TransportTexture in the GPU process. int GetPeerId(); // IPC::Channel::Listener. virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual void OnChannelError() OVERRIDE; virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; private: // Released all textures generated. void ReleaseTexturesInternal(); // Send the texture IDs to the GPU process. This will copy the set of // texture IDs. void SendTexturesInternal(const std::vector& textures); // Send the destroy message to the GPU process. void SendDestroyInternal(); //////////////////////////////////////////////////////////////////////////// // IPC Message Handlers void OnTransportTextureCreated(int32 peer_id); void OnCreateTextures(int32 n, uint32 width, uint32 height, int32 format); void OnReleaseTextures(); void OnTextureUpdated(int texture_id); MessageLoop* io_message_loop_; MessageLoop* render_message_loop_; scoped_refptr service_; IPC::Message::Sender* sender_; RendererGLContext* context_; int32 context_route_id_; int32 host_id_; int32 peer_id_; scoped_ptr init_task_; // A list of textures generated. std::vector textures_; // Callback when a texture is updated. scoped_ptr update_callback_; DISALLOW_COPY_AND_ASSIGN(TransportTextureHost); }; #endif // CONTENT_RENDERER_GPU_TRANSPORT_TEXTURE_HOST_H_