summaryrefslogtreecommitdiffstats
path: root/content/gpu
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-06 23:09:27 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-06 23:09:27 +0000
commiteb42af56881701abea1231ae8d6820d7b1125379 (patch)
tree91da6a64325becf4dbe3e21eb0a6a3c4cb835d47 /content/gpu
parent4d9dcff2b947ad34ce997397ab662c7e91667c07 (diff)
downloadchromium_src-eb42af56881701abea1231ae8d6820d7b1125379.zip
chromium_src-eb42af56881701abea1231ae8d6820d7b1125379.tar.gz
chromium_src-eb42af56881701abea1231ae8d6820d7b1125379.tar.bz2
Define TransportTexture for 'sharing' texture between gpu and renderer
The purpose of TransportTexture is to allow creating textures in the gpu process and be used in the renderer process. This is particularly useful for hardware video decoder where the video frames are in the form of textures. Creating these textures has to be originated from the GPU process, they are then used in the renderer process for compositing. This patch defines the class and has comments about its usage. BUG=None TEST=None Review URL: http://codereview.chromium.org/6765020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80715 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/gpu')
-rw-r--r--content/gpu/gpu_channel.cc31
-rw-r--r--content/gpu/gpu_channel.h14
-rw-r--r--content/gpu/transport_texture.cc107
-rw-r--r--content/gpu/transport_texture.h98
4 files changed, 248 insertions, 2 deletions
diff --git a/content/gpu/gpu_channel.cc b/content/gpu/gpu_channel.cc
index d531179..b81f9868 100644
--- a/content/gpu/gpu_channel.cc
+++ b/content/gpu/gpu_channel.cc
@@ -17,6 +17,7 @@
#include "content/common/gpu_messages.h"
#include "content/gpu/gpu_render_thread.h"
#include "content/gpu/gpu_video_service.h"
+#include "content/gpu/transport_texture.h"
#if defined(OS_POSIX)
#include "ipc/ipc_channel_posix.h"
@@ -132,6 +133,15 @@ void GpuChannel::DestroyCommandBufferByViewId(int32 render_view_id) {
}
#endif
+TransportTexture* GpuChannel::GetTransportTexture(int32 route_id) {
+ return transport_textures_.Lookup(route_id);
+}
+
+void GpuChannel::DestroyTransportTexture(int32 route_id) {
+ transport_textures_.Remove(route_id);
+ router_.RemoveRoute(route_id);
+}
+
bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg)
@@ -144,6 +154,8 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
OnCreateVideoDecoder)
IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyVideoDecoder,
OnDestroyVideoDecoder)
+ IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateTransportTexture,
+ OnCreateTransportTexture)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
DCHECK(handled);
@@ -231,7 +243,6 @@ void GpuChannel::OnCreateVideoDecoder(int32 context_route_id,
void GpuChannel::OnDestroyVideoDecoder(int32 decoder_id) {
#if defined(ENABLE_GPU)
- LOG(ERROR) << "GpuChannel::OnDestroyVideoDecoder";
GpuVideoService* service = GpuVideoService::GetInstance();
if (service == NULL)
return;
@@ -239,6 +250,24 @@ void GpuChannel::OnDestroyVideoDecoder(int32 decoder_id) {
#endif
}
+void GpuChannel::OnCreateTransportTexture(int32 context_route_id,
+ int32 host_id) {
+#if defined(ENABLE_GPU)
+ GpuCommandBufferStub* stub = stubs_.Lookup(context_route_id);
+ int32 route_id = GenerateRouteID();
+
+ scoped_ptr<TransportTexture> transport(
+ new TransportTexture(this, channel_.get(), stub->processor()->decoder(),
+ host_id, route_id));
+ router_.AddRoute(route_id, transport.get());
+ transport_textures_.AddWithID(transport.release(), route_id);
+
+ IPC::Message* msg = new GpuTransportTextureHostMsg_TransportTextureCreated(
+ host_id, route_id);
+ Send(msg);
+#endif
+}
+
bool GpuChannel::Init(MessageLoop* io_message_loop,
base::WaitableEvent* shutdown_event) {
// Check whether we're already initialized.
diff --git a/content/gpu/gpu_channel.h b/content/gpu/gpu_channel.h
index 860d7a1..497e47c 100644
--- a/content/gpu/gpu_channel.h
+++ b/content/gpu/gpu_channel.h
@@ -24,6 +24,7 @@ class GpuRenderThread;
class GpuWatchdogThread;
struct GPUCreateCommandBufferConfig;
class MessageLoop;
+class TransportTexture;
namespace base {
class WaitableEvent;
@@ -77,6 +78,13 @@ class GpuChannel : public IPC::Channel::Listener,
void DestroyCommandBufferByViewId(int32 render_view_id);
#endif
+ // Get the TransportTexture by ID.
+ TransportTexture* GetTransportTexture(int32 route_id);
+
+ // Destroy the TransportTexture by ID. This method is only called by
+ // TransportTexture to delete and detach itself.
+ void DestroyTransportTexture(int32 route_id);
+
private:
bool OnControlMessageReceived(const IPC::Message& msg);
@@ -91,10 +99,10 @@ class GpuChannel : public IPC::Channel::Listener,
uint32 parent_texture_id,
int32* route_id);
void OnDestroyCommandBuffer(int32 route_id);
-
void OnCreateVideoDecoder(int32 context_route_id,
int32 decoder_host_id);
void OnDestroyVideoDecoder(int32 decoder_id);
+ void OnCreateTransportTexture(int32 context_route_id, int32 host_id);
// The lifetime of objects of this class is managed by a GpuRenderThread. The
// GpuRenderThreads destroy all the GpuChannels that they own when they
@@ -120,6 +128,10 @@ class GpuChannel : public IPC::Channel::Listener,
StubMap stubs_;
#endif // defined (ENABLE_GPU)
+ // A collection of transport textures created.
+ typedef IDMap<TransportTexture, IDMapOwnPointer> TransportTextureMap;
+ TransportTextureMap transport_textures_;
+
bool log_messages_; // True if we should log sent and received messages.
gpu::gles2::DisallowedExtensions disallowed_extensions_;
GpuWatchdogThread* watchdog_thread_;
diff --git a/content/gpu/transport_texture.cc b/content/gpu/transport_texture.cc
new file mode 100644
index 0000000..e949c78
--- /dev/null
+++ b/content/gpu/transport_texture.cc
@@ -0,0 +1,107 @@
+// 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.
+
+#include "content/common/gpu_messages.h"
+#include "content/gpu/gpu_channel.h"
+#include "content/gpu/transport_texture.h"
+
+TransportTexture::TransportTexture(GpuChannel* channel,
+ IPC::Message::Sender* sender,
+ gpu::gles2::GLES2Decoder* decoder,
+ int32 host_id,
+ int32 route_id)
+ : channel_(channel),
+ sender_(sender),
+ decoder_(decoder),
+ host_id_(host_id),
+ route_id_(route_id) {
+}
+
+TransportTexture::~TransportTexture() {
+}
+
+void TransportTexture::CreateTextures(
+ int n, int width, int height, Format format, std::vector<int>* textures,
+ Task* done_task) {
+ output_textures_ = textures;
+ DCHECK(!create_task_.get());
+ create_task_.reset(done_task);
+
+ bool ret = sender_->Send(new GpuTransportTextureHostMsg_CreateTextures(
+ host_id_, n, width, height, static_cast<int>(format)));
+ if (!ret) {
+ LOG(ERROR) << "GpuTransportTexture_CreateTextures failed";
+ }
+}
+
+void TransportTexture::ReleaseTextures() {
+ texture_map_.clear();
+
+ bool ret = sender_->Send(new GpuTransportTextureHostMsg_ReleaseTextures(
+ host_id_));
+ if (!ret) {
+ LOG(ERROR) << "GpuTransportTexture_ReleaseTextures failed";
+ }
+}
+
+void TransportTexture::TextureUpdated(int texture_id) {
+ TextureMap::iterator iter = texture_map_.find(texture_id);
+ if (iter == texture_map_.end()) {
+ LOG(ERROR) << "Texture not found: " << texture_id;
+ return;
+ }
+
+ bool ret = sender_->Send(new GpuTransportTextureHostMsg_TextureUpdated(
+ host_id_, iter->second));
+ if (!ret) {
+ LOG(ERROR) << "GpuTransportTexture_TextureUpdated failed";
+ }
+}
+
+void TransportTexture::OnChannelConnected(int32 peer_pid) {
+}
+
+void TransportTexture::OnChannelError() {
+}
+
+bool TransportTexture::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(TransportTexture, msg)
+ IPC_MESSAGE_HANDLER(GpuTransportTextureMsg_Destroy,
+ OnDestroy)
+ IPC_MESSAGE_HANDLER(GpuTransportTextureMsg_TexturesCreated,
+ OnTexturesCreated)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ DCHECK(handled);
+ return handled;
+}
+
+void TransportTexture::OnDestroy() {
+ channel_->DestroyTransportTexture(route_id_);
+}
+
+void TransportTexture::OnTexturesCreated(std::vector<int> textures) {
+ bool ret = decoder_->MakeCurrent();
+ if (!ret) {
+ LOG(ERROR) << "Failed to switch context";
+ return;
+ }
+
+ output_textures_->clear();
+ for (size_t i = 0; i < textures.size(); ++i) {
+ uint32 gl_texture = 0;
+
+ // Translate the client texture id to service texture id.
+ ret = decoder_->GetServiceTextureId(textures[i], &gl_texture);
+ DCHECK(ret) << "Cannot translate client texture ID to service ID";
+ output_textures_->push_back(gl_texture);
+ texture_map_.insert(std::make_pair(gl_texture, textures[i]));
+ }
+
+ // Notify user that textures are ready.
+ create_task_->Run();
+ create_task_.reset();
+ output_textures_ = NULL;
+}
diff --git a/content/gpu/transport_texture.h b/content/gpu/transport_texture.h
new file mode 100644
index 0000000..577d277
--- /dev/null
+++ b/content/gpu/transport_texture.h
@@ -0,0 +1,98 @@
+// 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.
+
+// This clasis used together with TansportTextureHost in the renderer process
+// to provide a mechanism for an object in the GPU process to create textures
+// and be used in the renderer process.
+//
+// See content/gpu/transport_texture_host.h for usage and details.
+
+#ifndef CONTENT_GPU_TRANSPORT_TEXTURE_H_
+#define CONTENT_GPU_TRANSPORT_TEXTURE_H_
+
+#include <vector>
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/task.h"
+#include "ipc/ipc_channel.h"
+
+class GpuChannel;
+
+namespace gpu {
+namespace gles2 {
+class GLES2Decoder;
+} // namespace gles2
+} // namespace gpu
+
+class TransportTexture : public IPC::Channel::Listener {
+ public:
+ enum Format {
+ RGBA, // GL_RGBA
+ };
+
+ // |channel| is the owner of this object.
+ // |sender| is used to send send IPC messages.
+ // |decoder| is the decoder for GLES2 command buffer, used to convert texture
+ // IDs.
+ // |host_id| is ID of TransportTextureHost in Renderer process.
+ // |id| is ID of this object in GpuChannel.
+ TransportTexture(GpuChannel* channel,
+ IPC::Message::Sender* sender,
+ gpu::gles2::GLES2Decoder* decoder,
+ int32 host_id,
+ int32 route_id);
+ virtual ~TransportTexture();
+
+ // Create a set of textures of specified size and format. They will be
+ // stored in |textures| and |done_task| will be called.
+ // Textures IDs stored in |textures| are in the system GL context.
+ void CreateTextures(int n, int width, int height, Format format,
+ std::vector<int>* textures, Task* done_task);
+
+ // Release all textures that have previously been allocated.
+ void ReleaseTextures();
+
+ // Notify that the texture has been updated. Notification will be sent to the
+ // renderer process.
+ void TextureUpdated(int texture_id);
+
+ // IPC::Channel::Listener implementation.
+ virtual void OnChannelConnected(int32 peer_pid);
+ virtual void OnChannelError();
+ virtual bool OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Mapping from service (GPU) IDs to client (Renderer) IDs.
+ typedef std::map<int, int> TextureMap;
+
+ ///////////////////////////////////////////////////////////////////////////
+ // IPC Message Handlers
+ void OnDestroy();
+ void OnTexturesCreated(std::vector<int> textures);
+
+ GpuChannel* channel_;
+ IPC::Message::Sender* sender_;
+ gpu::gles2::GLES2Decoder* decoder_;
+
+ // ID of TransportTextureHost in the Renderer process.
+ int32 host_id_;
+
+ // ID of this object in GpuChannel.
+ int32 route_id_;
+
+ // Output pointer to write generated textures.
+ std::vector<int>* output_textures_;
+
+ // Task that gets called when textures are generated.
+ scoped_ptr<Task> create_task_;
+
+ // Mapping between service (GPU) IDs to client (Renderer) IDs.
+ TextureMap texture_map_;
+
+ DISALLOW_COPY_AND_ASSIGN(TransportTexture);
+};
+
+#endif // CONTENT_GPU_TRANSPORT_TEXTURE_H_