diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 18:58:54 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-16 18:58:54 +0000 |
commit | 4bbe6d0c3ceb04efe623184d299867d1f5a320f2 (patch) | |
tree | e3705f4cc2ebbf5c6de112ba92ce2a8cc434c2da /content | |
parent | 4d1ffe7bb8cf7d97dc66e4a72af992177b293052 (diff) | |
download | chromium_src-4bbe6d0c3ceb04efe623184d299867d1f5a320f2.zip chromium_src-4bbe6d0c3ceb04efe623184d299867d1f5a320f2.tar.gz chromium_src-4bbe6d0c3ceb04efe623184d299867d1f5a320f2.tar.bz2 |
Moved code not relating to GPU scheduling out of GpuScheduler and into GpuCommandBufferStub.
This was mostly a refactor because the code was awkward.
I also deleted the original gles2_demo since we have the gles2 book demos now.
THings still to do are a common way of setting up the few objects involved in initializing a command buffer that is now more-or-less duplicated in the gles2 conformance tests, the gles2 demos, the command buffer stub and the in-process webgl context. I also want to completely remove the reference to the decoder from the scheduler.
I tested WebGL on both windows and mac and saw no regressions. I checked the conformance tests, the gpu tests and am running by the try bots now. The gles2 demos still work.
Review URL: http://codereview.chromium.org/7782041
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101545 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r-- | content/common/gpu/gpu_channel.cc | 2 | ||||
-rw-r--r-- | content/common/gpu/gpu_command_buffer_stub.cc | 293 | ||||
-rw-r--r-- | content/common/gpu/gpu_command_buffer_stub.h | 55 | ||||
-rw-r--r-- | content/common/gpu/image_transport_surface_linux.cc | 19 | ||||
-rw-r--r-- | content/common/gpu/image_transport_surface_linux.h | 5 | ||||
-rw-r--r-- | content/common/gpu/media/gpu_video_decode_accelerator.cc | 4 |
6 files changed, 260 insertions, 118 deletions
diff --git a/content/common/gpu/gpu_channel.cc b/content/common/gpu/gpu_channel.cc index 0ad31501..61a92af 100644 --- a/content/common/gpu/gpu_channel.cc +++ b/content/common/gpu/gpu_channel.cc @@ -356,7 +356,7 @@ void GpuChannel::OnCreateTransportTexture(int32 context_route_id, int32 route_id = GenerateRouteID(); scoped_ptr<TransportTexture> transport( - new TransportTexture(this, channel_.get(), stub->scheduler()->decoder(), + new TransportTexture(this, channel_.get(), stub->decoder(), host_id, route_id)); router_.AddRoute(route_id, transport.get()); transport_textures_.AddWithID(transport.release(), route_id); diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 90c85da..13750bd 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -5,28 +5,22 @@ #if defined(ENABLE_GPU) #include "base/bind.h" +#include "base/command_line.h" #include "base/debug/trace_event.h" -#include "base/process_util.h" #include "base/shared_memory.h" #include "build/build_config.h" -#include "content/common/child_thread.h" #include "content/common/gpu/gpu_channel.h" #include "content/common/gpu/gpu_channel_manager.h" #include "content/common/gpu/gpu_command_buffer_stub.h" #include "content/common/gpu/gpu_messages.h" #include "content/common/gpu/gpu_watchdog.h" #include "gpu/command_buffer/common/constants.h" -#include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_surface.h" +#include "ui/gfx/gl/gl_switches.h" -#if defined(OS_WIN) -#include "base/win/wrapped_window_proc.h" -#elif defined(TOUCH_UI) +#if defined(TOUCH_UI) #include "content/common/gpu/image_transport_surface_linux.h" #endif -using gpu::Buffer; - GpuCommandBufferStub::GpuCommandBufferStub( GpuChannel* channel, GpuCommandBufferStub* share_group, @@ -54,6 +48,10 @@ GpuCommandBufferStub::GpuCommandBufferStub( parent_stub_for_initialization_(), parent_texture_for_initialization_(0), watchdog_(watchdog), +#if defined(OS_MACOSX) + swap_buffers_count_(0), + acknowledged_swap_buffers_count_(0), +#endif task_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { if (share_group) { context_group_ = share_group->context_group_; @@ -65,9 +63,7 @@ GpuCommandBufferStub::GpuCommandBufferStub( } GpuCommandBufferStub::~GpuCommandBufferStub() { - if (scheduler_.get()) { - scheduler_->Destroy(); - } + Destroy(); GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer( @@ -75,6 +71,18 @@ GpuCommandBufferStub::~GpuCommandBufferStub() { } bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { + // Ensure the appropriate GL context is current before handling any IPC + // messages directed at the command buffer. This ensures that the message + // handler can assume that the context is current. + if (decoder_.get()) { + if (!decoder_->MakeCurrent()) { + LOG(ERROR) << "Context lost because MakeCurrent failed."; + command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); + command_buffer_->SetParseError(gpu::error::kLostContext); + return false; + } + } + // Always use IPC_MESSAGE_HANDLER_DELAY_REPLY for synchronous message handlers // here. This is so the reply can be delayed if the scheduler is unscheduled. bool handled = true; @@ -114,9 +122,43 @@ bool GpuCommandBufferStub::IsScheduled() { return !scheduler_.get() || scheduler_->IsScheduled(); } -void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { +#if defined(OS_MACOSX) + +TransportDIB::Handle GpuCommandBufferStub::SetWindowSizeForTransportDIB( + const gfx::Size& size) { + return accelerated_surface_->SetTransportDIBSize(size); +} + +void GpuCommandBufferStub::SetTransportDIBAllocAndFree( + Callback2<size_t, TransportDIB::Handle*>::Type* allocator, + Callback1<TransportDIB::Id>::Type* deallocator) { + accelerated_surface_->SetTransportDIBAllocAndFree(allocator, deallocator); +} + +#endif // OS_MACOSX + +void GpuCommandBufferStub::Destroy() { + // The scheduler has raw references to the decoder and the command buffer so + // destroy it before those. scheduler_.reset(); + + if (decoder_.get()) { + decoder_->Destroy(); + decoder_.reset(); + } + command_buffer_.reset(); + + context_ = NULL; + surface_ = NULL; + +#if defined(OS_MACOSX) + accelerated_surface_.reset(); +#endif +} + +void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { + Destroy(); GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false); Send(reply_message); } @@ -141,95 +183,127 @@ void GpuCommandBufferStub::OnInitialize( base::SharedMemory shared_memory(ring_buffer, false); #endif - // Initialize the CommandBufferService and GpuScheduler. - if (command_buffer_->Initialize(&shared_memory, size)) { - scheduler_.reset(gpu::GpuScheduler::Create(command_buffer_.get(), - context_group_.get())); + if (!command_buffer_->Initialize(&shared_memory, size)) { + OnInitializeFailed(reply_message); + return; + } + + decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group_.get())); + + scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), + decoder_.get(), + NULL)); + + decoder_->set_engine(scheduler_.get()); + + if (handle_) { #if defined(TOUCH_UI) if (software_) { OnInitializeFailed(reply_message); return; } - scoped_refptr<gfx::GLSurface> surface; - if (handle_) - surface = ImageTransportSurface::CreateSurface( - channel_->gpu_channel_manager(), - render_view_id_, - renderer_id_, - route_id_); - else - surface = gfx::GLSurface::CreateOffscreenGLSurface(software_, - gfx::Size(1, 1)); - if (!surface.get()) { - LOG(ERROR) << "GpuCommandBufferStub: failed to create surface."; - OnInitializeFailed(reply_message); - return; - } + surface_ = ImageTransportSurface::CreateSurface( + channel_->gpu_channel_manager(), + render_view_id_, + renderer_id_, + route_id_); +#elif defined(OS_WIN) || defined(OS_LINUX) + surface_ = gfx::GLSurface::CreateViewGLSurface(software_, handle_); +#elif defined(OS_MACOSX) + surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_, + gfx::Size(1, 1)); +#endif + } else { + surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_, + gfx::Size(1, 1)); + } + + if (!surface_.get()) { + LOG(ERROR) << "Failed to create surface.\n"; + OnInitializeFailed(reply_message); + return; + } + + context_ = gfx::GLContext::CreateGLContext(channel_->share_group(), + surface_.get()); + if (!context_.get()) { + LOG(ERROR) << "Failed to create context.\n"; + OnInitializeFailed(reply_message); + return; + } - scoped_refptr<gfx::GLContext> context( - gfx::GLContext::CreateGLContext(channel_->share_group(), - surface.get())); - if (!context.get()) { - LOG(ERROR) << "GpuCommandBufferStub: failed to create context."; +#if defined(OS_MACOSX) + // On Mac OS X since we can not render on-screen we don't even + // attempt to create a view based GLContext. The only difference + // between "on-screen" and "off-screen" rendering on this platform + // is whether we allocate an AcceleratedSurface, which transmits the + // rendering results back to the browser. + if (handle_) { + accelerated_surface_.reset(new AcceleratedSurface()); + + // Note that although the GLContext is passed to Initialize and the + // GLContext will later be owned by the decoder, AcceleratedSurface does + // not hold on to the reference. It simply extracts the underlying GL + // context in order to share the namespace with another context. + if (!accelerated_surface_->Initialize(context_.get(), false)) { + LOG(ERROR) << "Failed to initialize AcceleratedSurface."; OnInitializeFailed(reply_message); return; } - - if (scheduler_->InitializeCommon( - surface, - context, - initial_size_, - disallowed_extensions_, - allowed_extensions_.c_str(), - requested_attribs_)) { -#else - if (scheduler_->Initialize( - handle_, - initial_size_, - software_, - disallowed_extensions_, - allowed_extensions_.c_str(), - requested_attribs_, - channel_->share_group())) { + } #endif - command_buffer_->SetPutOffsetChangeCallback( - NewCallback(scheduler_.get(), - &gpu::GpuScheduler::PutChanged)); - command_buffer_->SetParseErrorCallback( - NewCallback(this, &GpuCommandBufferStub::OnParseError)); - scheduler_->SetScheduledCallback( - NewCallback(channel_, &GpuChannel::OnScheduled)); + + // Initialize the decoder with either the view or pbuffer GLContext. + if (!decoder_->Initialize(surface_.get(), + context_.get(), + initial_size_, + disallowed_extensions_, + allowed_extensions_.c_str(), + requested_attribs_)) { + LOG(ERROR) << "Failed to initialize decoder."; + OnInitializeFailed(reply_message); + return; + } + + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableGPUServiceLogging)) { + decoder_->set_debug(true); + } + + command_buffer_->SetPutOffsetChangeCallback( + NewCallback(scheduler_.get(), + &gpu::GpuScheduler::PutChanged)); + command_buffer_->SetParseErrorCallback( + NewCallback(this, &GpuCommandBufferStub::OnParseError)); + scheduler_->SetScheduledCallback( + NewCallback(channel_, &GpuChannel::OnScheduled)); #if defined(OS_MACOSX) - scheduler_->SetSwapBuffersCallback( - NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); + decoder_->SetSwapBuffersCallback( + NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); #endif - // On TOUCH_UI, the ImageTransportSurface handles co-ordinating the - // resize with the browser process. The ImageTransportSurface sets it's - // own resize callback, so we shouldn't do it here. + // On TOUCH_UI, the ImageTransportSurface handles co-ordinating the + // resize with the browser process. The ImageTransportSurface sets it's + // own resize callback, so we shouldn't do it here. #if !defined(TOUCH_UI) - if (handle_ != gfx::kNullPluginWindow) { - scheduler_->SetResizeCallback( - NewCallback(this, &GpuCommandBufferStub::OnResize)); - } + if (handle_ != gfx::kNullPluginWindow) { + decoder_->SetResizeCallback( + NewCallback(this, &GpuCommandBufferStub::OnResize)); + } #endif - if (watchdog_) - scheduler_->SetCommandProcessedCallback( - NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); - if (parent_stub_for_initialization_) { - scheduler_->SetParent(parent_stub_for_initialization_->scheduler_.get(), - parent_texture_for_initialization_); - parent_stub_for_initialization_.reset(); - parent_texture_for_initialization_ = 0; - } + if (watchdog_) { + scheduler_->SetCommandProcessedCallback( + NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); + } - } else { - OnInitializeFailed(reply_message); - return; - } + if (parent_stub_for_initialization_) { + decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(), + parent_texture_for_initialization_); + parent_stub_for_initialization_.reset(); + parent_texture_for_initialization_ = 0; } GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true); @@ -247,9 +321,9 @@ void GpuCommandBufferStub::OnSetParent(int32 parent_route_id, bool result = true; if (scheduler_.get()) { - gpu::GpuScheduler* parent_scheduler = - parent_stub ? parent_stub->scheduler_.get() : NULL; - result = scheduler_->SetParent(parent_scheduler, parent_texture_id); + gpu::gles2::GLES2Decoder* parent_decoder = + parent_stub ? parent_stub->decoder_.get() : NULL; + result = decoder_->SetParent(parent_decoder, parent_texture_id); } else { // If we don't have a scheduler, it means that Initialize hasn't been called // yet. Keep around the requested parent stub and texture so that we can set @@ -399,7 +473,7 @@ void GpuCommandBufferStub::OnGetTransferBuffer( if (!channel_->renderer_process()) return; - Buffer buffer = command_buffer_->GetTransferBuffer(id); + gpu::Buffer buffer = command_buffer_->GetTransferBuffer(id); if (buffer.shared_memory) { // Assume service is responsible for duplicating the handle to the calling // process. @@ -417,6 +491,17 @@ void GpuCommandBufferStub::OnGetTransferBuffer( #if defined(OS_MACOSX) void GpuCommandBufferStub::OnSwapBuffers() { TRACE_EVENT0("gpu", "GpuCommandBufferStub::OnSwapBuffers"); + + DCHECK(decoder_.get()); + DCHECK(decoder_->GetGLContext()); + DCHECK(decoder_->GetGLContext()->IsCurrent(decoder_->GetGLSurface())); + + ++swap_buffers_count_; + + if (accelerated_surface_.get()) { + accelerated_surface_->SwapBuffers(); + } + if (handle_) { // To swap on OSX, we have to send a message to the browser to get the // context put onscreen. @@ -425,14 +510,20 @@ void GpuCommandBufferStub::OnSwapBuffers() { params.renderer_id = renderer_id_; params.render_view_id = render_view_id_; params.window = handle_; - params.surface_id = scheduler_->GetSurfaceId(); + params.surface_id = GetSurfaceId(); params.route_id = route_id(); - params.swap_buffers_count = scheduler_->swap_buffers_count(); + params.swap_buffers_count = swap_buffers_count_; gpu_channel_manager->Send( new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); scheduler_->SetScheduled(false); } } + +uint64 GpuCommandBufferStub::GetSurfaceId() { + if (!accelerated_surface_.get()) + return 0; + return accelerated_surface_->GetSurfaceId(); +} #endif void GpuCommandBufferStub::OnCommandProcessed() { @@ -452,9 +543,8 @@ void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( // AcceleratedSurfaceBuffersSwapped call. Upstream code listening to the // GpuCommandBufferMsg_SwapBuffers expects to be called one time for every // swap. So, send one SwapBuffers message for every outstanding swap. - uint64 delta = swap_buffers_count - - scheduler_->acknowledged_swap_buffers_count(); - scheduler_->set_acknowledged_swap_buffers_count(swap_buffers_count); + uint64 delta = swap_buffers_count - acknowledged_swap_buffers_count_; + acknowledged_swap_buffers_count_ = swap_buffers_count; for(uint64 i = 0; i < delta; i++) { // Wake up the GpuScheduler to start doing work again. When the scheduler @@ -474,7 +564,7 @@ void GpuCommandBufferStub::OnResize(gfx::Size size) { // On Mac, we need to tell the browser about the new IOSurface handle, // asynchronously. - uint64 new_backing_store = scheduler_->SetWindowSizeForIOSurface(size); + uint64 new_backing_store = accelerated_surface_->SetSurfaceSize(size); if (new_backing_store) { GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params; params.renderer_id = renderer_id_; @@ -509,20 +599,19 @@ void GpuCommandBufferStub::OnResize(gfx::Size size) { #endif // defined(OS_MACOSX) } - void GpuCommandBufferStub::ViewResized() { #if defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN) DCHECK(handle_ != gfx::kNullPluginWindow); scheduler_->SetScheduled(true); +#endif - // Recreate the view surface to match the window size. TODO(apatrick): this is - // likely not necessary on all platforms. - gfx::GLContext* context = scheduler_->decoder()->GetGLContext(); - gfx::GLSurface* surface = scheduler_->decoder()->GetGLSurface(); - context->ReleaseCurrent(surface); - if (surface) { - surface->Destroy(); - surface->Initialize(); +#if defined(OS_WIN) + // Recreate the view surface to match the window size. Swap chains do not + // automatically resize with window size with D3D. + context_->ReleaseCurrent(surface_.get()); + if (surface_.get()) { + surface_->Destroy(); + surface_->Initialize(); } #endif } diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index c214aaa..f0fefab 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h @@ -8,13 +8,11 @@ #if defined(ENABLE_GPU) -#include <queue> #include <string> #include <vector> #include "base/id_map.h" #include "base/memory/weak_ptr.h" -#include "base/process.h" #include "base/task.h" #include "content/common/gpu/media/gpu_video_decode_accelerator.h" #include "gpu/command_buffer/service/command_buffer_service.h" @@ -22,8 +20,15 @@ #include "gpu/command_buffer/service/gpu_scheduler.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message.h" +#include "ui/gfx/gl/gl_context.h" +#include "ui/gfx/gl/gl_surface.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/size.h" +#include "ui/gfx/surface/transport_dib.h" + +#if defined(OS_MACOSX) +#include "ui/gfx/surface/accelerated_surface_mac.h" +#endif class GpuChannel; class GpuWatchdog; @@ -58,7 +63,7 @@ class GpuCommandBufferStub // Whether this command buffer can currently handle IPC messages. bool IsScheduled(); - // Get the GLContext associated with this object. + gpu::gles2::GLES2Decoder* decoder() const { return decoder_.get(); } gpu::GpuScheduler* scheduler() const { return scheduler_.get(); } // Identifies the renderer process. @@ -71,19 +76,28 @@ class GpuCommandBufferStub // to the same renderer process. int32 route_id() const { return route_id_; } -#if defined(OS_WIN) - // Called only by the compositor window's window proc - void OnCompositorWindowPainted(); -#endif // defined(OS_WIN) - void ViewResized(); #if defined(OS_MACOSX) // Called only by the GpuChannel. void AcceleratedSurfaceBuffersSwapped(uint64 swap_buffers_count); -#endif // defined(OS_MACOSX) + + // Needed only on Mac OS X, which does not render into an on-screen + // window and therefore requires the backing store to be resized + // manually. Returns an opaque identifier for the new backing store. + // There are two versions of this method: one for use with the IOSurface + // available in Mac OS X 10.6; and, one for use with the + // TransportDIB-based version used on Mac OS X 10.5. + virtual TransportDIB::Handle SetWindowSizeForTransportDIB( + const gfx::Size& size); + virtual void SetTransportDIBAllocAndFree( + Callback2<size_t, TransportDIB::Handle*>::Type* allocator, + Callback1<TransportDIB::Id>::Type* deallocator); +#endif private: + void Destroy(); + // Cleans up and sends reply if OnInitialize failed. void OnInitializeFailed(IPC::Message* reply_message); @@ -119,6 +133,10 @@ class GpuCommandBufferStub #if defined(OS_MACOSX) void OnSwapBuffers(); + + // Returns the id of the current surface that is being rendered to + // (or 0 if no such surface has been created). + uint64 GetSurfaceId(); #endif void OnCommandProcessed(); @@ -150,7 +168,10 @@ class GpuCommandBufferStub int32 render_view_id_; scoped_ptr<gpu::CommandBufferService> command_buffer_; + scoped_ptr<gpu::gles2::GLES2Decoder> decoder_; scoped_ptr<gpu::GpuScheduler> scheduler_; + scoped_refptr<gfx::GLContext> context_; + scoped_refptr<gfx::GLSurface> surface_; // SetParent may be called before Initialize, in which case we need to keep // around the parent stub, so that Initialize can set the parent correctly. @@ -158,12 +179,26 @@ class GpuCommandBufferStub uint32 parent_texture_for_initialization_; GpuWatchdog* watchdog_; - ScopedRunnableMethodFactory<GpuCommandBufferStub> task_factory_; // Zero or more video decoders owned by this stub, keyed by their // decoder_route_id. IDMap<GpuVideoDecodeAccelerator, IDMapOwnPointer> video_decoders_; +#if defined(OS_MACOSX) + // To prevent the GPU process from overloading the browser process, + // we need to track the number of swap buffers calls issued and + // acknowledged per on-screen context, and keep the GPU from getting + // too far ahead of the browser. Note that this + // is also predicated on a flow control mechanism between the + // renderer and GPU processes. + uint64 swap_buffers_count_; + uint64 acknowledged_swap_buffers_count_; + scoped_ptr<AcceleratedSurface> accelerated_surface_; + scoped_ptr<Callback0::Type> wrapped_swap_buffers_callback_; +#endif + + ScopedRunnableMethodFactory<GpuCommandBufferStub> task_factory_; + DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub); }; diff --git a/content/common/gpu/image_transport_surface_linux.cc b/content/common/gpu/image_transport_surface_linux.cc index bd8615e..e0117e6 100644 --- a/content/common/gpu/image_transport_surface_linux.cc +++ b/content/common/gpu/image_transport_surface_linux.cc @@ -425,11 +425,11 @@ ImageTransportHelper::~ImageTransportHelper() { } bool ImageTransportHelper::Initialize() { - gpu::GpuScheduler* scheduler = Scheduler(); - if (!scheduler) + gpu::gles2::GLES2Decoder* decoder = Decoder(); + if (!decoder) return false; - scheduler->SetResizeCallback( + decoder->SetResizeCallback( NewCallback(this, &ImageTransportHelper::Resize)); return true; @@ -507,4 +507,17 @@ gpu::GpuScheduler* ImageTransportHelper::Scheduler() { return stub->scheduler(); } +gpu::gles2::GLES2Decoder* ImageTransportHelper::Decoder() { + GpuChannel* channel = manager_->LookupChannel(renderer_id_); + if (!channel) + return NULL; + + GpuCommandBufferStub* stub = + channel->LookupCommandBuffer(command_buffer_id_); + if (!stub) + return NULL; + + return stub->decoder(); +} + #endif // defined(USE_GPU) diff --git a/content/common/gpu/image_transport_surface_linux.h b/content/common/gpu/image_transport_surface_linux.h index ef25655..3dddd959 100644 --- a/content/common/gpu/image_transport_surface_linux.h +++ b/content/common/gpu/image_transport_surface_linux.h @@ -25,6 +25,10 @@ class GLSurface; namespace gpu { class GpuScheduler; + +namespace gles2 { +class GLES2Decoder; +} } class ImageTransportSurface { @@ -71,6 +75,7 @@ class ImageTransportHelper : public IPC::Channel::Listener { private: gpu::GpuScheduler* Scheduler(); + gpu::gles2::GLES2Decoder* Decoder(); // IPC::Message handlers. void OnSetSurfaceACK(uint64 surface_id); diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index 42d1f65..9859a85 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc @@ -134,8 +134,8 @@ void GpuVideoDecodeAccelerator::OnAssignPictureBuffers( const std::vector<int32>& buffer_ids, const std::vector<uint32>& texture_ids, const std::vector<gfx::Size>& sizes) { - DCHECK(stub_ && stub_->scheduler()); // Ensure already Initialize()'d. - gpu::gles2::GLES2Decoder* command_decoder = stub_->scheduler()->decoder(); + DCHECK(stub_ && stub_->decoder()); // Ensure already Initialize()'d. + gpu::gles2::GLES2Decoder* command_decoder = stub_->decoder(); std::vector<media::PictureBuffer> buffers; for (uint32 i = 0; i < buffer_ids.size(); ++i) { |