diff options
30 files changed, 471 insertions, 1552 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) { diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc index 01f3760..c32a803 100644 --- a/gpu/command_buffer/client/cmd_buffer_helper_test.cc +++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -77,7 +77,7 @@ class CommandBufferHelperTest : public testing::Test { .WillRepeatedly( Invoke(do_jump_command_.get(), &DoJumpCommand::DoCommand)); - gpu_scheduler_.reset(GpuScheduler::CreateForTests( + gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( gpu_scheduler_.get(), &GpuScheduler::PutChanged)); diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc index 883d752..8f2f609 100644 --- a/gpu/command_buffer/client/fenced_allocator_test.cc +++ b/gpu/command_buffer/client/fenced_allocator_test.cc @@ -51,7 +51,7 @@ class BaseFencedAllocatorTest : public testing::Test { 0, api_mock_.get()); - gpu_scheduler_.reset(GpuScheduler::CreateForTests( + gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( gpu_scheduler_.get(), &GpuScheduler::PutChanged)); diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc deleted file mode 100644 index 72937d5..0000000 --- a/gpu/command_buffer/client/gles2_demo.cc +++ /dev/null @@ -1,241 +0,0 @@ -// 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 file implements a standalone executable demo of using GLES2 over -// command buffers. This code is temporary as the setup that happens -// here is in a state of flux. Eventually there will be several versions of -// setup, one for trusted code, one for pepper, one for NaCl, and maybe others. - -#include <windows.h> -#include <windowsx.h> -#include <shellapi.h> -#include <stdlib.h> -#include <stdio.h> -#include "base/at_exit.h" -#include "base/command_line.h" -#include "base/callback.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/message_loop.h" -#include "base/shared_memory.h" -#include "gpu/command_buffer/service/context_group.h" -#include "gpu/command_buffer/service/gpu_scheduler.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/client/gles2_lib.h" -#include "gpu/command_buffer/client/gles2_demo_c.h" -#include "gpu/command_buffer/client/gles2_demo_cc.h" -#include "ui/gfx/gl/gl_implementation.h" -#include "ui/gfx/gl/gl_surface.h" - -using base::SharedMemory; -using gpu::Buffer; -using gpu::GpuScheduler; -using gpu::CommandBufferService; -using gpu::gles2::GLES2CmdHelper; -using gpu::gles2::GLES2Implementation; - -#if defined(OS_WIN) -HINSTANCE g_instance; -#endif - -class GLES2Demo { - public: - GLES2Demo(); - - bool GLES2Demo::Setup(void* hwnd, int32 size); - - private: - DISALLOW_COPY_AND_ASSIGN(GLES2Demo); -}; - -GLES2Demo::GLES2Demo() { -} - -bool GLES2Demo::Setup(void* hwnd, int32 size) { -#if defined(OS_WIN) - InitializeGLBindings(gfx::kGLImplementationEGLGLES2); -#else - InitializeGLBindings(gfx::kGLImplementationDesktopGL); -#endif - - scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService); - if (!command_buffer->Initialize(size)) - return NULL; - - gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(true)); - GpuScheduler* gpu_scheduler = GpuScheduler::Create(command_buffer.get(), - group.get()); - if (!gpu_scheduler->Initialize(reinterpret_cast<HWND>(hwnd), - gfx::Size(), - false, - gpu::gles2::DisallowedExtensions(), - NULL, - std::vector<int32>(), - NULL)) { - return NULL; - } - - command_buffer->SetPutOffsetChangeCallback( - NewCallback(gpu_scheduler, &GpuScheduler::PutChanged)); - - GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); - if (!helper->Initialize(size)) { - // TODO(gman): cleanup. - return false; - } - - size_t transfer_buffer_size = 512 * 1024; - int32 transfer_buffer_id = - command_buffer->CreateTransferBuffer(transfer_buffer_size, -1); - Buffer transfer_buffer = - command_buffer->GetTransferBuffer(transfer_buffer_id); - if (!transfer_buffer.ptr) - return false; - - - gles2::Initialize(); - gles2::SetGLContext(new GLES2Implementation(helper, - transfer_buffer.size, - transfer_buffer.ptr, - transfer_buffer_id, - false, - true)); - - GLFromCPPInit(); - - return command_buffer.release() != NULL; -} - -#if defined(OS_WIN) -LRESULT CALLBACK WindowProc( - HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { - switch (msg) { - case WM_CLOSE: - DestroyWindow(hwnd); - break; - case WM_DESTROY: - PostQuitMessage(0); - break; - case WM_PAINT: { - GLFromCPPDraw(); - GLFromCDraw(); - // TODO(gman): Not sure how SwapBuffer should be exposed. - gles2::GetGLContext()->SwapBuffers(); - break; - } - default: - return ::DefWindowProc(hwnd, msg, w_param, l_param); - } - return 0; -} - -void ProcessMessages(void* in_hwnd) { - HWND hwnd = reinterpret_cast<HWND>(in_hwnd); - MSG msg; - - bool done = false; - while (!done) { - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) { - done = true; - } - // dispatch the message - TranslateMessage(&msg); - DispatchMessage(&msg); - } - if (!done) { - InvalidateRect(hwnd, NULL, TRUE); - } - } -} - -#endif - -void* SetupWindow() { -#if defined(OS_WIN) - WNDCLASSEX wc = {0}; - wc.lpszClassName = L"MY_WINDOWS_CLASS"; - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = ::WindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = g_instance; - wc.hIcon = ::LoadIcon(g_instance, IDI_APPLICATION); - wc.hIconSm = NULL; - wc.hCursor = ::LoadCursor(g_instance, IDC_ARROW); - wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(BLACK_BRUSH)); - wc.lpszMenuName = NULL; - - if (!::RegisterClassEx(&wc)) - return false; - - // Leaving this window onscreen leads to a redraw error which makes it - // a hassle to debug tests in an IDE, so we place the window somewhere that - // won't happen. - HWND hwnd = ::CreateWindowExW( - NULL, - wc.lpszClassName, - L"", - WS_OVERLAPPEDWINDOW, - 10, - 0, - 512, - 512, - 0, - 0, - g_instance, - 0); - - if (hwnd == NULL) { - return false; - } - - ::ShowWindow(hwnd, SW_SHOWNORMAL); - - - return hwnd; -#else -#error Need code. -#endif -} - -#if defined(OS_WIN) -int WINAPI WinMain(HINSTANCE instance, - HINSTANCE prev_instance, - LPSTR command_line, - int command_show) { - g_instance = instance; - int argc = 1; - const char* const argv[] = { - "gles2_demo.exe" - }; - -#else -int main(int argc, char** argv) { -#endif - CommandLine::Init(argc, argv); - - const int32 kCommandBufferSize = 1024 * 1024; - - base::AtExitManager at_exit_manager; - MessageLoopForUI message_loop; - - gfx::GLSurface::InitializeOneOff(); - - GLES2Demo* demo = new GLES2Demo(); - - void* hwnd = SetupWindow(); - if (!hwnd) { - ::fprintf(stdout, "Could not setup window.\n"); - return EXIT_FAILURE; - } - - demo->Setup(hwnd, kCommandBufferSize); - - ProcessMessages(hwnd); - - return EXIT_SUCCESS; -} diff --git a/gpu/command_buffer/client/gles2_demo_c.c b/gpu/command_buffer/client/gles2_demo_c.c deleted file mode 100644 index e369745..0000000 --- a/gpu/command_buffer/client/gles2_demo_c.c +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2009 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 file is here so other GLES2 related files can have a common set of -// includes where appropriate. - -#include <GLES2/gl2.h> -#include "command_buffer/client/gles2_demo_c.h" - -void GLFromCDraw() { - // glClear(GL_COLOR_BUFFER_BIT); -} - - diff --git a/gpu/command_buffer/client/gles2_demo_c.h b/gpu/command_buffer/client/gles2_demo_c.h deleted file mode 100644 index d4d69e9..0000000 --- a/gpu/command_buffer/client/gles2_demo_c.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2009 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. - -// A Test that we can access GL from c. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_C_H -#define GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_C_H - -#ifdef __cplusplus -extern "C" { -#endif - -void GLFromCDraw(); - -#ifdef __cplusplus -} -#endif - -#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_C_H - - diff --git a/gpu/command_buffer/client/gles2_demo_cc.cc b/gpu/command_buffer/client/gles2_demo_cc.cc deleted file mode 100644 index 80837ea..0000000 --- a/gpu/command_buffer/client/gles2_demo_cc.cc +++ /dev/null @@ -1,408 +0,0 @@ -// 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 file is here so other GLES2 related files can have a common set of -// includes where appropriate. - -#include "../client/gles2_demo_cc.h" -#include "../common/logging.h" - -#include <math.h> -#include <string> - -// This is here so we have at least some idea that the inline path is working. -#define GLES2_INLINE_OPTIMIZATION -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#include "../common/logging.h" - -namespace { - -int g_frameCount = 0; -int g_textureIndex = 0; -int g_numTextures = 1; -GLuint g_textures[5]; -int g_textureLoc = -1; -GLuint g_programObject = 0; -GLuint g_worldMatrixLoc = 0; -GLuint g_vbo = 0; -GLsizei g_texCoordOffset = 0; -int g_angle = 0; - -void CheckGLError(const char* func_name, int line_no) { -#ifndef NDEBUG - GLenum error = GL_NO_ERROR; - while ((error = glGetError()) != GL_NO_ERROR) { - GPU_DLOG(gpu::ERROR) << "GL Error in " << func_name << " at line " - << line_no << ": " << error; - } -#endif -} - -GLuint LoadShader(GLenum type, const char* shaderSrc) { - CheckGLError("LoadShader", __LINE__); - GLuint shader = glCreateShader(type); - if (shader == 0) { - return 0; - } - // Load the shader source - glShaderSource(shader, 1, &shaderSrc, NULL); - // Compile the shader - glCompileShader(shader); - // Check the compile status - GLint value = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &value); - if (value == 0) { - char buffer[1024]; - GLsizei length = 0; - glGetShaderInfoLog(shader, sizeof(buffer), &length, buffer); - std::string log(buffer, length); - GPU_DLOG(gpu::ERROR) << "Error compiling shader:" << log; - glDeleteShader(shader); - return 0; - } - return shader; -} - -void InitShaders() { - static const char* vShaderStr = - "uniform mat4 worldMatrix;\n" - "attribute vec3 g_Position;\n" - "attribute vec2 g_TexCoord0;\n" - "varying vec2 texCoord;\n" - "void main()\n" - "{\n" - " gl_Position = worldMatrix *\n" - " vec4(g_Position.x, g_Position.y, g_Position.z, 1.0);\n" - " texCoord = g_TexCoord0;\n" - "}\n"; - static const char* fShaderStr = - "precision mediump float;" - "uniform sampler2D tex;\n" - "varying vec2 texCoord;\n" - "void main()\n" - "{\n" - " gl_FragColor = texture2D(tex, texCoord);\n" - "}\n"; - - CheckGLError("InitShaders", __LINE__); - GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr); - GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr); - // Create the program object - GLuint programObject = glCreateProgram(); - if (programObject == 0) { - GPU_DLOG(gpu::ERROR) << "Creating program failed"; - return; - } - glAttachShader(programObject, vertexShader); - glAttachShader(programObject, fragmentShader); - // Bind g_Position to attribute 0 - // Bind g_TexCoord0 to attribute 1 - glBindAttribLocation(programObject, 0, "g_Position"); - glBindAttribLocation(programObject, 1, "g_TexCoord0"); - // Link the program - glLinkProgram(programObject); - // Check the link status - GLint linked = 0; - glGetProgramiv(programObject, GL_LINK_STATUS, &linked); - if (linked == 0) { - char buffer[1024]; - GLsizei length = 0; - glGetProgramInfoLog(programObject, sizeof(buffer), &length, buffer); - std::string log(buffer, length); - GPU_DLOG(gpu::ERROR) << "Error linking program:" << log; - glDeleteProgram(programObject); - return; - } - g_programObject = programObject; - g_worldMatrixLoc = glGetUniformLocation(g_programObject, "worldMatrix"); - g_textureLoc = glGetUniformLocation(g_programObject, "tex"); - glGenBuffers(1, &g_vbo); - glBindBuffer(GL_ARRAY_BUFFER, g_vbo); - static float vertices[] = { - 0.25, 0.75, 0.0, - -0.75, 0.75, 0.0, - -0.75, -0.25, 0.0, - 0.25, 0.75, 0.0, - -0.75, -0.25, 0.0, - 0.25, -0.25, 0.0, - }; - static float texCoords[] = { - 1.0, 1.0, - 0.0, 1.0, - 0.0, 0.0, - 1.0, 1.0, - 0.0, 0.0, - 1.0, 0.0, - }; - g_texCoordOffset = sizeof(vertices); - glBufferData(GL_ARRAY_BUFFER, - sizeof(vertices) + sizeof(texCoords), - NULL, - GL_STATIC_DRAW); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); - glBufferSubData(GL_ARRAY_BUFFER, g_texCoordOffset, - sizeof(texCoords), texCoords); - CheckGLError("InitShaders", __LINE__); -} - -GLuint CreateCheckerboardTexture() { - CheckGLError("CreateCheckerboardTexture", __LINE__); - static unsigned char pixels[] = { - 255, 255, 255, - 0, 0, 0, - 0, 0, 0, - 255, 255, 255, - }; - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, - pixels); - CheckGLError("CreateCheckerboardTexture", __LINE__); - return texture; -} - -GLuint CreateCompressedTexture( - const void* data, - GLsizeiptr size, - GLenum format, - GLint width, - GLint height) { - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glCompressedTexImage2D( - GL_TEXTURE_2D, 0, format, width, height, 0, size, data); - CheckGLError("CreateCompressedTxture", __LINE__); - return texture; -} - -GLuint LoadDXT1RGBTexture() { - static unsigned char data[] = { - 0x00, 0xd0, 0x00, 0xef, 0x00, 0xaa, 0x95, 0xd5, - 0x00, 0x90, 0x57, 0xff, 0x00, 0xaa, 0xff, 0x55, - 0x00, 0x88, 0x99, 0xff, 0x00, 0xaa, 0xff, 0x55, - 0x20, 0xb8, 0xe4, 0xf6, 0x00, 0xaa, 0x5b, 0x5d, - 0x21, 0x09, 0xe6, 0x27, 0x15, 0x15, 0x15, 0x15, - 0xd7, 0xbd, 0xff, 0xff, 0x56, 0x16, 0x16, 0x56, - 0x00, 0x00, 0xff, 0xff, 0x55, 0x00, 0x00, 0x55, - 0xe0, 0x08, 0xa9, 0x2f, 0x51, 0x58, 0x56, 0x54, - 0xff, 0x07, 0x15, 0x09, 0x40, 0x6a, 0xd5, 0xd5, - 0xd7, 0xbd, 0xff, 0xff, 0x56, 0x16, 0x16, 0x16, - 0x91, 0x08, 0xff, 0xff, 0x55, 0xff, 0x00, 0x03, - 0xfe, 0x07, 0x5b, 0x09, 0x01, 0xa9, 0x55, 0xff, - 0x0d, 0x10, 0x18, 0xe8, 0xea, 0x15, 0x95, 0x55, - 0x08, 0x88, 0x3c, 0xe7, 0x55, 0x55, 0xff, 0x00, - 0x10, 0x20, 0x18, 0xe8, 0xa8, 0x54, 0x56, 0x55, - 0x1f, 0x78, 0x15, 0xf8, 0x00, 0xaa, 0x55, 0x55, - }; - return CreateCompressedTexture( - data, sizeof(data), GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 16, 16); -} - -GLuint LoadDXT1RGBATexture() { - static unsigned char data[] = { - 0xff, 0xff, 0x90, 0xee, 0x00, 0xaa, 0xff, 0x55, - 0x53, 0xde, 0xdd, 0xff, 0x55, 0x55, 0x00, 0xff, - 0xc9, 0xb4, 0xdd, 0xff, 0x55, 0x55, 0xaa, 0xff, - 0x6f, 0xee, 0xdd, 0xff, 0x55, 0x55, 0xa8, 0x03, - 0x60, 0xa3, 0xa5, 0xe5, 0x55, 0x55, 0xaa, 0x00, - 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x80, 0xab, 0xc2, 0xc4, 0xff, 0x55, 0xaa, 0xff, - 0x60, 0x9b, 0xa5, 0xe5, 0x57, 0x56, 0xaa, 0x00, - 0x1f, 0xbf, 0xff, 0xf7, 0x55, 0x55, 0xaa, 0x00, - 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xfe, 0xbe, 0x7e, 0xdf, 0xff, 0xaa, 0x55, 0x00, - 0xfe, 0xbe, 0xff, 0xf7, 0x54, 0x56, 0xaa, 0x00, - 0xfa, 0x4c, 0x7e, 0x9e, 0x55, 0xaa, 0x00, 0x00, - 0xbb, 0x2c, 0x98, 0x54, 0xff, 0xff, 0x55, 0xaa, - 0xfa, 0x4c, 0x7e, 0x9e, 0x55, 0xaa, 0x00, 0x00, - 0xfa, 0x4c, 0x7e, 0x9e, 0x55, 0xaa, 0x00, 0x00, - }; - return CreateCompressedTexture( - data, sizeof(data), GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 16, 16); -} - -GLuint LoadDXT3RGBATexture() { - static unsigned char data[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xa3, 0x22, 0x03, 0x03, 0x55, 0xff, 0xaa, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0xcf, 0x7c, 0xc3, 0x12, 0x55, 0x55, 0x55, 0x54, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0x83, 0x1a, 0x03, 0x03, 0x55, 0xff, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, - 0xcf, 0x7c, 0xc3, 0x12, 0x55, 0x55, 0x55, 0x54, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc3, 0x59, 0x63, 0x32, 0x55, 0xff, 0xaa, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, - 0x8f, 0x94, 0x03, 0x4a, 0x54, 0x94, 0x94, 0x54, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, - 0xa3, 0x59, 0x43, 0x2a, 0x55, 0xff, 0xaa, 0x00, - 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, - 0xaf, 0x84, 0x03, 0x42, 0x54, 0x55, 0x55, 0x55, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc3, 0xa0, 0x83, 0x71, 0x55, 0xff, 0xaa, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, - 0x0f, 0xb4, 0x43, 0x81, 0x54, 0x94, 0x94, 0x94, - 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc3, 0xa0, 0x83, 0x69, 0x55, 0xff, 0xaa, 0x00, - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xc3, 0xa0, 0x83, 0x69, 0x55, 0xfd, 0xaa, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x23, 0xd0, 0xa3, 0xb0, 0x55, 0xff, 0xaa, 0x00, - 0x00, 0x40, 0x00, 0x40, 0xff, 0xff, 0xff, 0xff, - 0xf0, 0xc3, 0x43, 0xc0, 0x94, 0x94, 0x55, 0x55, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x23, 0xd0, 0xa3, 0xb0, 0x55, 0xff, 0xaa, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0x23, 0xd0, 0xa3, 0xb0, 0x55, 0xff, 0xaa, 0x00, - }; - return CreateCompressedTexture( - data, sizeof(data), GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 16, 16); -} - -GLuint LoadDXT5RGBATexture() { - static unsigned char data[] = { - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0xdd, 0x03, 0x92, 0x2d, 0x2d, 0x2d, 0x2d, - 0x04, 0xfb, 0xff, 0xff, 0xff, 0x49, 0x02, 0xdb, - 0x97, 0xf6, 0x32, 0xcd, 0xc0, 0xc0, 0x7b, 0xc0, - 0xfb, 0xff, 0x49, 0x92, 0x24, 0x00, 0x60, 0xdb, - 0x11, 0xcd, 0x67, 0x82, 0x78, 0x78, 0x5e, 0x78, - 0x04, 0xfb, 0xff, 0xff, 0xff, 0xf9, 0x8f, 0xff, - 0x2e, 0xac, 0xc4, 0x71, 0x15, 0x15, 0x15, 0x14, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0xdd, 0x03, 0x92, 0x2d, 0x2d, 0x2d, 0x2d, - 0x04, 0x43, 0xb0, 0x0d, 0x3b, 0xb0, 0x03, 0xdb, - 0xb8, 0xf6, 0xd5, 0xd5, 0x60, 0x60, 0x60, 0x60, - 0xfb, 0x00, 0x49, 0x02, 0x00, 0x00, 0x90, 0x24, - 0xb0, 0xbc, 0x26, 0x7a, 0x78, 0x78, 0x78, 0x78, - 0x04, 0xf7, 0xf8, 0x9f, 0xff, 0xf9, 0x9f, 0xff, - 0x0e, 0xac, 0x83, 0x69, 0x34, 0x35, 0x35, 0x35, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0xdd, 0x03, 0x92, 0x2d, 0x2d, 0x2d, 0x2d, - 0x04, 0x43, 0xb0, 0x0d, 0x3b, 0xb0, 0x03, 0x3b, - 0xb8, 0xf6, 0xd5, 0xd5, 0x60, 0x60, 0x60, 0x60, - 0xfb, 0xff, 0xb6, 0x0d, 0x00, 0x49, 0x92, 0x24, - 0x11, 0xcd, 0x67, 0x82, 0x78, 0x5e, 0x78, 0x78, - 0xea, 0xff, 0x4a, 0xd2, 0x24, 0x49, 0x92, 0x24, - 0x0e, 0xac, 0xc4, 0x71, 0x15, 0x15, 0x15, 0x15, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0xdd, 0x03, 0x92, 0x2d, 0x2d, 0x2d, 0x2d, - 0xfd, 0x00, 0x49, 0x9c, 0xc4, 0x00, 0x00, 0x00, - 0xb8, 0xf6, 0x53, 0xcd, 0xe0, 0xe0, 0x7f, 0xe0, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf1, 0xcc, 0x46, 0x82, 0x78, 0x78, 0x78, 0x78, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0e, 0xac, 0xc4, 0x71, 0x15, 0x15, 0x15, 0x15, - }; - return CreateCompressedTexture( - data, sizeof(data), GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 16, 16); -} - -} // anonymous namespace. - -void GLFromCPPInit() { - CheckGLError("GLFromCPPInit", __LINE__); - g_textures[0] = CreateCheckerboardTexture(); - glClearColor(0.f, 0.f, .7f, 1.f); - const char* extensions = - reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); - if (strstr(extensions, "GL_EXT_texture_compression_dxt1")) { - g_textures[g_numTextures++] = LoadDXT1RGBTexture(); - g_textures[g_numTextures++] = LoadDXT1RGBATexture(); - } - if (strstr(extensions, "GL_CHROMIUM_texture_compression_dxt3")) { - g_textures[g_numTextures++] = LoadDXT3RGBATexture(); - } - if (strstr(extensions, "GL_CHROMIUM_texture_compression_dxt5")) { - g_textures[g_numTextures++] = LoadDXT5RGBATexture(); - } - InitShaders(); - CheckGLError("GLFromCPPInit", __LINE__); - - char buf[128]; - glReadPixels(0, 0, 1, 1, 0, 0, buf); - CheckGLError("GLFromCPPInit:ReadPixels", __LINE__); -} - -void GLFromCPPDraw() { - const float kPi = 3.1415926535897932384626433832795f; - - CheckGLError("GLFromCPPDraw", __LINE__); - // TODO(kbr): base the angle on time rather than on ticks - g_angle = (g_angle + 1) % 360; - // Rotate about the Z axis - GLfloat rot_matrix[16]; - GLfloat cos_angle = cosf(static_cast<GLfloat>(g_angle) * kPi / 180.0f); - GLfloat sin_angle = sinf(static_cast<GLfloat>(g_angle) * kPi / 180.0f); - // OpenGL matrices are column-major - rot_matrix[0] = cos_angle; - rot_matrix[1] = sin_angle; - rot_matrix[2] = 0.0f; - rot_matrix[3] = 0.0f; - - rot_matrix[4] = -sin_angle; - rot_matrix[5] = cos_angle; - rot_matrix[6] = 0.0f; - rot_matrix[7] = 0.0f; - - rot_matrix[8] = 0.0f; - rot_matrix[9] = 0.0f; - rot_matrix[10] = 1.0f; - rot_matrix[11] = 0.0f; - - rot_matrix[12] = 0.0f; - rot_matrix[13] = 0.0f; - rot_matrix[14] = 0.0f; - rot_matrix[15] = 1.0f; - - g_frameCount++; - if (g_frameCount > 60) - { - g_frameCount = 0; - g_textureIndex = (g_textureIndex + 1) % g_numTextures; - } - - // Note: the viewport is automatically set up to cover the entire Canvas. - // Clear the color buffer - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - CheckGLError("GLFromCPPDraw", __LINE__); - // Use the program object - glUseProgram(g_programObject); - CheckGLError("GLFromCPPDraw", __LINE__); - // Set up the model matrix - glUniformMatrix4fv(g_worldMatrixLoc, 1, GL_FALSE, rot_matrix); - - // Load the vertex data - glBindBuffer(GL_ARRAY_BUFFER, g_vbo); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, - reinterpret_cast<const void*>(g_texCoordOffset)); - CheckGLError("GLFromCPPDraw", __LINE__); - // Bind the texture to texture unit 0 - glBindTexture(GL_TEXTURE_2D, g_textures[g_textureIndex]); - CheckGLError("GLFromCPPDraw", __LINE__); - // Point the uniform sampler to texture unit 0 - glUniform1i(g_textureLoc, 0); - CheckGLError("GLFromCPPDraw", __LINE__); - glDrawArrays(GL_TRIANGLES, 0, 6); - CheckGLError("GLFromCPPDraw", __LINE__); - glFlush(); -} diff --git a/gpu/command_buffer/client/gles2_demo_cc.h b/gpu/command_buffer/client/gles2_demo_cc.h deleted file mode 100644 index 158ba43..0000000 --- a/gpu/command_buffer/client/gles2_demo_cc.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 2009 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. - -// A Test that we can access GL from C++. - -#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H -#define GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H - -void GLFromCPPInit(); -void GLFromCPPDraw(); - -#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H - - diff --git a/gpu/command_buffer/client/mapped_memory_unittest.cc b/gpu/command_buffer/client/mapped_memory_unittest.cc index 735ac23..ee9b025 100644 --- a/gpu/command_buffer/client/mapped_memory_unittest.cc +++ b/gpu/command_buffer/client/mapped_memory_unittest.cc @@ -49,7 +49,7 @@ class MappedMemoryTestBase : public testing::Test { 0, api_mock_.get()); - gpu_scheduler_.reset(GpuScheduler::CreateForTests( + gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( gpu_scheduler_.get(), &GpuScheduler::PutChanged)); diff --git a/gpu/command_buffer/client/ring_buffer_test.cc b/gpu/command_buffer/client/ring_buffer_test.cc index a816393..ee21614 100644 --- a/gpu/command_buffer/client/ring_buffer_test.cc +++ b/gpu/command_buffer/client/ring_buffer_test.cc @@ -71,7 +71,7 @@ class BaseRingBufferTest : public testing::Test { 0, api_mock_.get()); - gpu_scheduler_.reset(GpuScheduler::CreateForTests( + gpu_scheduler_.reset(new GpuScheduler( command_buffer_.get(), NULL, parser_)); command_buffer_->SetPutOffsetChangeCallback(NewCallback( gpu_scheduler_.get(), &GpuScheduler::PutChanged)); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index eef54c3..530342b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -2362,9 +2362,8 @@ void GLES2DecoderImpl::Destroy() { if (context_.get()) { context_->ReleaseCurrent(NULL); - context_->Destroy(); + context_ = NULL; } - context_ = NULL; offscreen_target_frame_buffer_.reset(); offscreen_target_color_texture_.reset(); diff --git a/gpu/command_buffer/service/gpu_scheduler.cc b/gpu/command_buffer/service/gpu_scheduler.cc index 70f84a4..a6442e9 100644 --- a/gpu/command_buffer/service/gpu_scheduler.cc +++ b/gpu/command_buffer/service/gpu_scheduler.cc @@ -19,119 +19,32 @@ using ::base::SharedMemory; namespace gpu { -GpuScheduler* GpuScheduler::Create(CommandBuffer* command_buffer, - gles2::ContextGroup* group) { - DCHECK(command_buffer); - - gles2::GLES2Decoder* decoder = gles2::GLES2Decoder::Create(group); - - GpuScheduler* scheduler = new GpuScheduler(command_buffer, - decoder, - NULL); - - decoder->set_engine(scheduler); - - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableGPUServiceLogging)) { - decoder->set_debug(true); - } - - return scheduler; -} - -GpuScheduler* GpuScheduler::CreateForTests(CommandBuffer* command_buffer, - gles2::GLES2Decoder* decoder, - CommandParser* parser) { - DCHECK(command_buffer); - GpuScheduler* scheduler = new GpuScheduler(command_buffer, - decoder, - parser); - - return scheduler; -} - -GpuScheduler::~GpuScheduler() { - Destroy(); -} - -bool GpuScheduler::InitializeCommon( - const scoped_refptr<gfx::GLSurface>& surface, - const scoped_refptr<gfx::GLContext>& context, - const gfx::Size& size, - const gles2::DisallowedExtensions& disallowed_extensions, - const char* allowed_extensions, - const std::vector<int32>& attribs) { - DCHECK(context); - - if (!context->MakeCurrent(surface)) - return false; - -#if !defined(OS_MACOSX) && !defined(TOUCH_UI) - // Set up swap interval for onscreen contexts. - if (!surface->IsOffscreen()) { - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) - context->SetSwapInterval(0); - else - context->SetSwapInterval(1); - } -#endif - +GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, + gles2::GLES2Decoder* decoder, + CommandParser* parser) + : command_buffer_(command_buffer), + decoder_(decoder), + parser_(parser), + unscheduled_count_(0) { // Map the ring buffer and create the parser. - Buffer ring_buffer = command_buffer_->GetRingBuffer(); - if (ring_buffer.ptr) { - parser_.reset(new CommandParser(ring_buffer.ptr, - ring_buffer.size, - 0, - ring_buffer.size, - 0, - decoder_.get())); - } else { - parser_.reset(new CommandParser(NULL, 0, 0, 0, 0, - decoder_.get())); - } - - // Initialize the decoder with either the view or pbuffer GLContext. - // TODO(apatrick): The GpuScheduler should know nothing about the surface the - // decoder is rendering to. Get rid of the surface parameter. - if (!decoder_->Initialize(surface, - context, - size, - disallowed_extensions, - allowed_extensions, - attribs)) { - LOG(ERROR) << "GpuScheduler::InitializeCommon failed because decoder " - << "failed to initialize."; - Destroy(); - return false; - } - - return true; -} - -void GpuScheduler::DestroyCommon() { - if (decoder_.get()) { - decoder_->MakeCurrent(); - decoder_->Destroy(); - decoder_.reset(); + if (!parser) { + Buffer ring_buffer = command_buffer_->GetRingBuffer(); + if (ring_buffer.ptr) { + parser_.reset(new CommandParser(ring_buffer.ptr, + ring_buffer.size, + 0, + ring_buffer.size, + 0, + decoder_)); + } else { + parser_.reset(new CommandParser(NULL, 0, 0, 0, 0, + decoder_)); + } } - - parser_.reset(); -} - -bool GpuScheduler::SetParent(GpuScheduler* parent_scheduler, - uint32 parent_texture_id) { - if (parent_scheduler) - return decoder_->SetParent(parent_scheduler->decoder_.get(), - parent_texture_id); - else - return decoder_->SetParent(NULL, 0); } -#if defined(OS_MACOSX) -namespace { -const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; +GpuScheduler::~GpuScheduler() { } -#endif void GpuScheduler::PutChanged() { TRACE_EVENT1("gpu", "GpuScheduler:PutChanged", "this", this); @@ -143,23 +56,6 @@ void GpuScheduler::PutChanged() { if (state.error != error::kNoError) return; - if (decoder_.get()) { - if (!decoder_->MakeCurrent()) { - LOG(ERROR) << "Context lost because MakeCurrent failed."; - command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); - command_buffer_->SetParseError(error::kLostContext); - return; - } - } - -#if defined(OS_MACOSX) - bool do_rate_limiting = surface_.get() != NULL; - - // Don't swamp the browser process with SwapBuffers calls it can't handle. - DCHECK(!do_rate_limiting || - swap_buffers_count_ - acknowledged_swap_buffers_count_ == 0); -#endif - error::Error error = error::kNoError; while (!parser_->IsEmpty()) { error = parser_->ProcessCommand(); @@ -226,28 +122,9 @@ int32 GpuScheduler::GetGetOffset() { return parser_->get(); } -void GpuScheduler::SetResizeCallback( - Callback1<gfx::Size>::Type* callback) { - decoder_->SetResizeCallback(callback); -} - void GpuScheduler::SetCommandProcessedCallback( Callback0::Type* callback) { command_processed_callback_.reset(callback); } -GpuScheduler::GpuScheduler(CommandBuffer* command_buffer, - gles2::GLES2Decoder* decoder, - CommandParser* parser) - : command_buffer_(command_buffer), - decoder_(decoder), - parser_(parser), - unscheduled_count_(0), -#if defined(OS_MACOSX) - swap_buffers_count_(0), - acknowledged_swap_buffers_count_(0), -#endif - method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { -} - } // namespace gpu diff --git a/gpu/command_buffer/service/gpu_scheduler.h b/gpu/command_buffer/service/gpu_scheduler.h index 72ffe26..32b072c 100644 --- a/gpu/command_buffer/service/gpu_scheduler.h +++ b/gpu/command_buffer/service/gpu_scheduler.h @@ -5,77 +5,29 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_H_ #define GPU_COMMAND_BUFFER_SERVICE_GPU_SCHEDULER_H_ -#include <map> -#include <queue> -#include <vector> - #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/shared_memory.h" -#include "base/task.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/command_buffer/service/cmd_buffer_engine.h" #include "gpu/command_buffer/service/cmd_parser.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.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 - -namespace gfx { -class GLContext; -class GLShareGroup; -class GLSurface; -} namespace gpu { -namespace gles2 { -class ContextGroup; -} -// This class processes commands in a command buffer. It is event driven and -// posts tasks to the current message loop to do additional work. +// This class schedules commands that have been flushed. They are received via +// a command buffer and forwarded to a command parser. TODO(apatrick): This +// class should not know about the decoder. Do not add additional dependencies +// on it. class GpuScheduler : public CommandBufferEngine { public: - // If a group is not passed in one will be created. - static GpuScheduler* Create(CommandBuffer* command_buffer, - gles2::ContextGroup* group); - - // This constructor is for unit tests. - static GpuScheduler* CreateForTests(CommandBuffer* command_buffer, - gles2::GLES2Decoder* decoder, - CommandParser* parser); + GpuScheduler(CommandBuffer* command_buffer, + gles2::GLES2Decoder* decoder, + CommandParser* parser); virtual ~GpuScheduler(); - // Platform specific code to create GLContexts and GLSurfaces that are - // handed off to the next function. - bool Initialize(gfx::PluginWindowHandle hwnd, - const gfx::Size& size, - bool software, - const gles2::DisallowedExtensions& disallowed_extensions, - const char* allowed_extensions, - const std::vector<int32>& attribs, - gfx::GLShareGroup* share_group); - - // Takes ownership of GLSurface and GLContext. - bool InitializeCommon( - const scoped_refptr<gfx::GLSurface>& surface, - const scoped_refptr<gfx::GLContext>& context, - const gfx::Size& size, - const gles2::DisallowedExtensions& disallowed_extensions, - const char* allowed_extensions, - const std::vector<int32>& attribs); - - void Destroy(); - void DestroyCommon(); - - bool SetParent(GpuScheduler* parent_scheduler, uint32 parent_texture_id); - void PutChanged(); // Sets whether commands should be processed by this scheduler. Setting to @@ -97,84 +49,29 @@ class GpuScheduler : public CommandBufferEngine { virtual bool SetGetOffset(int32 offset); virtual int32 GetGetOffset(); -#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() const; - uint64 acknowledged_swap_buffers_count() const; - void set_acknowledged_swap_buffers_count( - uint64 acknowledged_swap_buffers_count); - - // 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 uint64 SetWindowSizeForIOSurface(const gfx::Size& size); - virtual TransportDIB::Handle SetWindowSizeForTransportDIB( - const gfx::Size& size); - virtual void SetTransportDIBAllocAndFree( - Callback2<size_t, TransportDIB::Handle*>::Type* allocator, - Callback1<TransportDIB::Id>::Type* deallocator); - // Returns the id of the current surface that is being rendered to - // (or 0 if no such surface has been created). - virtual uint64 GetSurfaceId(); - - void DidDestroySurface(); - - // Sets a callback which is called when a SwapBuffers command is processed. - // Must be called after Initialize(). - // It is not defined on which thread this callback is called. - void SetSwapBuffersCallback(Callback0::Type* callback); -#endif - - // Sets a callback that is called when a glResizeCHROMIUM command - // is processed. - void SetResizeCallback(Callback1<gfx::Size>::Type* callback); - void SetCommandProcessedCallback(Callback0::Type* callback); - // Get the GLES2Decoder associated with this scheduler. - gles2::GLES2Decoder* decoder() const { return decoder_.get(); } - private: - // If a group is not passed in one will be created. - GpuScheduler(CommandBuffer* command_buffer, - gles2::GLES2Decoder* decoder, - CommandParser* parser); - -#if defined(OS_MACOSX) - // Called via a callback just before we are supposed to call the - // user's swap buffers callback. - void WillSwapBuffers(); -#endif // The GpuScheduler holds a weak reference to the CommandBuffer. The // CommandBuffer owns the GpuScheduler and holds a strong reference to it // through the ProcessCommands callback. CommandBuffer* command_buffer_; - scoped_ptr<gles2::GLES2Decoder> decoder_; + // Does not own decoder. TODO(apatrick): The GpuScheduler shouldn't need a + // pointer to the decoder, it is only used to initialize the CommandParser, + // which could be an argument to the constructor, and to determine the + // reason for context lost. + gles2::GLES2Decoder* decoder_; + + // TODO(apatrick): The GpuScheduler currently creates and owns the parser. + // This should be an argument to the constructor. scoped_ptr<CommandParser> parser_; // Greater than zero if this is waiting to be rescheduled before continuing. int unscheduled_count_; scoped_ptr<Callback0::Type> scheduled_callback_; - -#if defined(OS_MACOSX) - uint64 swap_buffers_count_; - uint64 acknowledged_swap_buffers_count_; - scoped_ptr<AcceleratedSurface> surface_; - scoped_ptr<Callback0::Type> wrapped_swap_buffers_callback_; -#endif - - ScopedRunnableMethodFactory<GpuScheduler> method_factory_; scoped_ptr<Callback0::Type> command_processed_callback_; }; diff --git a/gpu/command_buffer/service/gpu_scheduler_linux.cc b/gpu/command_buffer/service/gpu_scheduler_linux.cc deleted file mode 100644 index 7cb7689..0000000 --- a/gpu/command_buffer/service/gpu_scheduler_linux.cc +++ /dev/null @@ -1,61 +0,0 @@ -// 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 "gpu/command_buffer/service/gpu_scheduler.h" -#include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_share_group.h" -#include "ui/gfx/gl/gl_surface.h" - -using ::base::SharedMemory; - -namespace gpu { - -bool GpuScheduler::Initialize( - gfx::PluginWindowHandle window, - const gfx::Size& size, - bool software, - const gles2::DisallowedExtensions& disallowed_extensions, - const char* allowed_extensions, - const std::vector<int32>& attribs, - gfx::GLShareGroup* share_group) { -#if defined(TOUCH_UI) - NOTIMPLEMENTED(); - return false; -#endif - - // Create either a view or pbuffer based GLSurface. - scoped_refptr<gfx::GLSurface> surface; - if (window) - surface = gfx::GLSurface::CreateViewGLSurface(software, window); - else - surface = gfx::GLSurface::CreateOffscreenGLSurface(software, - gfx::Size(1, 1)); - if (!surface.get()) { - LOG(ERROR) << "GpuScheduler::Initialize failed.\n"; - Destroy(); - return false; - } - - // Create a GLContext and attach the surface. - scoped_refptr<gfx::GLContext> context( - gfx::GLContext::CreateGLContext(share_group, surface.get())); - if (!context.get()) { - LOG(ERROR) << "CreateGLContext failed.\n"; - Destroy(); - return false; - } - - return InitializeCommon(surface, - context, - size, - disallowed_extensions, - allowed_extensions, - attribs); -} - -void GpuScheduler::Destroy() { - DestroyCommon(); -} - -} // namespace gpu diff --git a/gpu/command_buffer/service/gpu_scheduler_mac.cc b/gpu/command_buffer/service/gpu_scheduler_mac.cc deleted file mode 100644 index b172db7..0000000 --- a/gpu/command_buffer/service/gpu_scheduler_mac.cc +++ /dev/null @@ -1,147 +0,0 @@ -// 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 "gpu/command_buffer/service/gpu_scheduler.h" -#include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_share_group.h" -#include "ui/gfx/gl/gl_surface.h" - -using ::base::SharedMemory; - -namespace gpu { - -bool GpuScheduler::Initialize( - gfx::PluginWindowHandle window, - const gfx::Size& size, - bool software, - const gles2::DisallowedExtensions& disallowed_extensions, - const char* allowed_extensions, - const std::vector<int32>& attribs, - gfx::GLShareGroup* share_group) { - scoped_refptr<gfx::GLSurface> surface( - gfx::GLSurface::CreateOffscreenGLSurface(software, gfx::Size(1, 1))); - if (!surface.get()) { - LOG(ERROR) << "CreateOffscreenGLSurface failed.\n"; - Destroy(); - return false; - } - - // Create a GLContext and attach the surface. - scoped_refptr<gfx::GLContext> context( - gfx::GLContext::CreateGLContext(share_group, surface.get())); - if (!context.get()) { - LOG(ERROR) << "CreateGLContext failed.\n"; - Destroy(); - return false; - } - - // 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 (window) { - 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 (!surface_->Initialize(context.get(), false)) { - LOG(ERROR) << "GpuScheduler::Initialize failed to " - << "initialize AcceleratedSurface."; - Destroy(); - return false; - } - } - - return InitializeCommon(surface, - context, - size, - disallowed_extensions, - allowed_extensions, - attribs); -} - -void GpuScheduler::Destroy() { - if (surface_.get()) { - surface_->Destroy(); - surface_.reset(); - } - - DestroyCommon(); -} - -uint64 GpuScheduler::SetWindowSizeForIOSurface(const gfx::Size& size) { - // Note: The following line changes the current context again. - return surface_->SetSurfaceSize(size); -} - -TransportDIB::Handle GpuScheduler::SetWindowSizeForTransportDIB( - const gfx::Size& size) { - return surface_->SetTransportDIBSize(size); -} - -void GpuScheduler::SetTransportDIBAllocAndFree( - Callback2<size_t, TransportDIB::Handle*>::Type* allocator, - Callback1<TransportDIB::Id>::Type* deallocator) { - surface_->SetTransportDIBAllocAndFree(allocator, deallocator); -} - -uint64 GpuScheduler::GetSurfaceId() { - if (!surface_.get()) - return 0; - return surface_->GetSurfaceId(); -} - -uint64 GpuScheduler::swap_buffers_count() const { - return swap_buffers_count_; -} - -uint64 GpuScheduler::acknowledged_swap_buffers_count() const { - return acknowledged_swap_buffers_count_; -} - -void GpuScheduler::set_acknowledged_swap_buffers_count( - uint64 acknowledged_swap_buffers_count) { - acknowledged_swap_buffers_count_ = acknowledged_swap_buffers_count; -} - -void GpuScheduler::DidDestroySurface() { - // When a browser window with a GpuScheduler is closed, the render process - // will attempt to finish all GL commands, it will busy-wait on the GPU - // process until the command queue is empty. If a paint is pending, the GPU - // process won't process any GL commands until the browser sends a paint ack, - // but since the browser window is already closed, it will never arrive. - // To break this infinite loop, the browser tells the GPU process that the - // surface became invalid, which causes the GPU process to not wait for paint - // acks. - surface_.reset(); -} - -void GpuScheduler::SetSwapBuffersCallback( - Callback0::Type* callback) { - wrapped_swap_buffers_callback_.reset(callback); - decoder_->SetSwapBuffersCallback( - NewCallback(this, - &GpuScheduler::WillSwapBuffers)); -} - -void GpuScheduler::WillSwapBuffers() { - DCHECK(decoder_.get()); - DCHECK(decoder_->GetGLContext()); - DCHECK(decoder_->GetGLContext()->IsCurrent(decoder_->GetGLSurface())); - - ++swap_buffers_count_; - - if (surface_.get()) { - surface_->SwapBuffers(); - } - - if (wrapped_swap_buffers_callback_.get()) { - wrapped_swap_buffers_callback_->Run(); - } -} - -} // namespace gpu diff --git a/gpu/command_buffer/service/gpu_scheduler_unittest.cc b/gpu/command_buffer/service/gpu_scheduler_unittest.cc index 4fb54b4..ce4fa11 100644 --- a/gpu/command_buffer/service/gpu_scheduler_unittest.cc +++ b/gpu/command_buffer/service/gpu_scheduler_unittest.cc @@ -46,7 +46,7 @@ class GpuSchedulerTest : public testing::Test { async_api_.reset(new StrictMock<AsyncAPIMock>); - decoder_ = new gles2::MockGLES2Decoder(); + decoder_.reset(new gles2::MockGLES2Decoder()); parser_ = new CommandParser(buffer_, kRingBufferEntries, @@ -55,13 +55,9 @@ class GpuSchedulerTest : public testing::Test { 0, async_api_.get()); - scheduler_.reset(gpu::GpuScheduler::CreateForTests(command_buffer_.get(), - decoder_, - parser_)); - - EXPECT_CALL(*decoder_, Destroy()) - .Times(1) - .RetiresOnSaturation(); + scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), + decoder_.get(), + parser_)); } virtual void TearDown() { @@ -80,7 +76,7 @@ class GpuSchedulerTest : public testing::Test { scoped_ptr<base::SharedMemory> shared_memory_; Buffer shared_memory_buffer_; int32* buffer_; - gles2::MockGLES2Decoder* decoder_; + scoped_ptr<gles2::MockGLES2Decoder> decoder_; CommandParser* parser_; scoped_ptr<AsyncAPIMock> async_api_; scoped_ptr<GpuScheduler> scheduler_; @@ -146,19 +142,6 @@ TEST_F(GpuSchedulerTest, ProcessesTwoCommands) { scheduler_->PutChanged(); } -TEST_F(GpuSchedulerTest, SchedulerSetsTheGLContext) { - EXPECT_CALL(*decoder_, MakeCurrent()) - .WillOnce(Return(true)) - .WillOnce(Return(true)); - - CommandBuffer::State state; - state.put_offset = 0; - EXPECT_CALL(*command_buffer_, GetState()) - .WillRepeatedly(Return(state)); - - scheduler_->PutChanged(); -} - TEST_F(GpuSchedulerTest, SetsErrorCodeOnCommandBuffer) { CommandHeader* header = reinterpret_cast<CommandHeader*>(&buffer_[0]); header[0].command = 7; diff --git a/gpu/command_buffer/service/gpu_scheduler_win.cc b/gpu/command_buffer/service/gpu_scheduler_win.cc deleted file mode 100644 index 72a463b..0000000 --- a/gpu/command_buffer/service/gpu_scheduler_win.cc +++ /dev/null @@ -1,60 +0,0 @@ -// 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 <windows.h> - -#include "gpu/command_buffer/service/gpu_scheduler.h" -#include "ui/gfx/gl/gl_context.h" -#include "ui/gfx/gl/gl_share_group.h" -#include "ui/gfx/gl/gl_surface.h" - -using ::base::SharedMemory; - -namespace gpu { - -bool GpuScheduler::Initialize( - gfx::PluginWindowHandle window, - const gfx::Size& size, - bool software, - const gles2::DisallowedExtensions& disallowed_extensions, - const char* allowed_extensions, - const std::vector<int32>& attribs, - gfx::GLShareGroup* share_group) { - // Create either a view or pbuffer based GLSurface. - scoped_refptr<gfx::GLSurface> surface; - if (window) { - surface = gfx::GLSurface::CreateViewGLSurface(software, window); - } else { - surface = gfx::GLSurface::CreateOffscreenGLSurface(software, - gfx::Size(1, 1)); - } - - if (!surface.get()) { - LOG(ERROR) << "GpuScheduler::Initialize failed.\n"; - Destroy(); - return false; - } - - // Create a GLContext and attach the surface. - scoped_refptr<gfx::GLContext> context( - gfx::GLContext::CreateGLContext(share_group, surface.get())); - if (!context.get()) { - LOG(ERROR) << "CreateGLContext failed.\n"; - Destroy(); - return false; - } - - return InitializeCommon(surface, - context, - size, - disallowed_extensions, - allowed_extensions, - attribs); -} - -void GpuScheduler::Destroy() { - DestroyCommon(); -} - -} // namespace gpu diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 30e4b5e..2fea47b 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -5,10 +5,11 @@ #include "gpu/demos/framework/window.h" #include "base/callback.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/client/gles2_implementation.h" #include "gpu/command_buffer/client/gles2_lib.h" -#include "gpu/command_buffer/service/command_buffer_service.h" -#include "gpu/command_buffer/service/gpu_scheduler.h" +#include "gpu/command_buffer/service/context_group.h" #include "gpu/demos/framework/demo.h" #include "gpu/demos/framework/demo_factory.h" @@ -50,47 +51,63 @@ void Window::OnPaint() { ::gles2::GetGLContext()->SwapBuffers(); } -// TODO(apatrick): It looks like all the resources allocated here leak. We -// should fix that if we want to use this Window class for anything beyond this -// simple use case. bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) { - scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService); - if (!command_buffer->Initialize(kCommandBufferSize)) { + command_buffer_.reset(new CommandBufferService); + if (!command_buffer_->Initialize(kCommandBufferSize)) { return false; } - GpuScheduler* gpu_scheduler( - GpuScheduler::Create(command_buffer.get(), NULL)); - if (!gpu_scheduler->Initialize(hwnd, gfx::Size(), false, - gpu::gles2::DisallowedExtensions(), - NULL, std::vector<int32>(), - NULL)) { + gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(true)); + + decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get())); + if (!decoder_.get()) + return false; + + gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), + decoder_.get(), + NULL)); + + decoder_->set_engine(gpu_scheduler_.get()); + + surface_ = gfx::GLSurface::CreateViewGLSurface(false, hwnd); + if (!surface_.get()) return false; - } - command_buffer->SetPutOffsetChangeCallback( - NewCallback(gpu_scheduler, &GpuScheduler::PutChanged)); + context_ = gfx::GLContext::CreateGLContext(NULL, surface_.get()); + if (!context_.get()) + return false; - GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); - if (!helper->Initialize(kCommandBufferSize)) { - // TODO(alokp): cleanup. + std::vector<int32> attribs; + if (!decoder_->Initialize(surface_.get(), + context_.get(), + gfx::Size(), + gpu::gles2::DisallowedExtensions(), + NULL, + attribs)) { return false; } + command_buffer_->SetPutOffsetChangeCallback( + NewCallback(gpu_scheduler_.get(), &GpuScheduler::PutChanged)); + + gles2_cmd_helper_.reset(new GLES2CmdHelper(command_buffer_.get())); + if (!gles2_cmd_helper_->Initialize(kCommandBufferSize)) + return false; + int32 transfer_buffer_id = - command_buffer->CreateTransferBuffer(kTransferBufferSize, -1); + command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1); Buffer transfer_buffer = - command_buffer->GetTransferBuffer(transfer_buffer_id); + command_buffer_->GetTransferBuffer(transfer_buffer_id); if (transfer_buffer.ptr == NULL) return false; ::gles2::Initialize(); - ::gles2::SetGLContext(new GLES2Implementation(helper, + ::gles2::SetGLContext(new GLES2Implementation(gles2_cmd_helper_.get(), transfer_buffer.size, transfer_buffer.ptr, transfer_buffer_id, false, true)); - return command_buffer.release() != NULL; + return true; } } // namespace demos diff --git a/gpu/demos/framework/window.h b/gpu/demos/framework/window.h index 3054def..4c6cd46 100644 --- a/gpu/demos/framework/window.h +++ b/gpu/demos/framework/window.h @@ -6,6 +6,12 @@ #define GPU_DEMOS_FRAMEWORK_WINDOW_H_ #include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/client/gles2_cmd_helper.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/command_buffer/service/gpu_scheduler.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "ui/gfx/gl/gl_context.h" +#include "ui/gfx/gl/gl_surface.h" #include "ui/gfx/native_widget_types.h" namespace gpu { @@ -40,6 +46,13 @@ class Window { gfx::NativeWindow window_handle_; scoped_ptr<Demo> demo_; + scoped_ptr<gpu::CommandBufferService> command_buffer_; + scoped_ptr<gpu::GpuScheduler> gpu_scheduler_; + scoped_ptr<gpu::gles2::GLES2Decoder> decoder_; + scoped_refptr<gfx::GLContext> context_; + scoped_refptr<gfx::GLSurface> surface_; + scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_; + DISALLOW_COPY_AND_ASSIGN(Window); }; diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index da0ac3c..f6016bc 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc @@ -6,10 +6,7 @@ #include <vector> #include "gpu/command_buffer/client/gles2_lib.h" -#include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/context_group.h" -#include "gpu/command_buffer/service/gles2_cmd_decoder.h" -#include "gpu/command_buffer/service/gpu_scheduler.h" #include "gpu/gles2_conform_support/egl/config.h" #include "gpu/gles2_conform_support/egl/surface.h" @@ -31,22 +28,20 @@ Display::~Display() { } bool Display::Initialize() { - using gpu::CommandBufferService; - scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService); + scoped_ptr<gpu::CommandBufferService> command_buffer( + new gpu::CommandBufferService); if (!command_buffer->Initialize(kCommandBufferSize)) return false; - using gpu::Buffer; int32 transfer_buffer_id = command_buffer->CreateTransferBuffer(kTransferBufferSize, -1); - Buffer transfer_buffer = + gpu::Buffer transfer_buffer = command_buffer->GetTransferBuffer(transfer_buffer_id); if (transfer_buffer.ptr == NULL) return false; - using gpu::gles2::GLES2CmdHelper; - scoped_ptr<GLES2CmdHelper> cmd_helper( - new GLES2CmdHelper(command_buffer.get())); + scoped_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper( + new gpu::gles2::GLES2CmdHelper(command_buffer.get())); if (!cmd_helper->Initialize(kCommandBufferSize)) return false; @@ -106,19 +101,39 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config, return EGL_NO_SURFACE; } - using gpu::GpuScheduler; - std::vector<int32> attribs; gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(true)); - scoped_ptr<GpuScheduler> gpu_scheduler( - GpuScheduler::Create(command_buffer_.get(), group.get())); - if (!gpu_scheduler->Initialize( - win, gfx::Size(), false, gpu::gles2::DisallowedExtensions(), NULL, - attribs, NULL)) + + decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get())); + if (!decoder_.get()) return EGL_NO_SURFACE; + gpu_scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), + decoder_.get(), + NULL)); + + decoder_->set_engine(gpu_scheduler_.get()); + + gl_surface_ = gfx::GLSurface::CreateViewGLSurface(false, win); + if (!gl_surface_.get()) + return EGL_NO_SURFACE; + + gl_context_ = gfx::GLContext::CreateGLContext(NULL, gl_surface_.get()); + if (!gl_context_.get()) + return EGL_NO_SURFACE; + + std::vector<int32> attribs; + if (!decoder_->Initialize(gl_surface_.get(), + gl_context_.get(), + gfx::Size(), + gpu::gles2::DisallowedExtensions(), + NULL, + attribs)) { + return EGL_NO_SURFACE; + } + command_buffer_->SetPutOffsetChangeCallback( - NewCallback(gpu_scheduler.get(), &GpuScheduler::PutChanged)); - gpu_scheduler_.reset(gpu_scheduler.release()); + NewCallback(gpu_scheduler_.get(), &gpu::GpuScheduler::PutChanged)); + surface_.reset(new Surface(win)); return surface_.get(); @@ -127,6 +142,9 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config, void Display::DestroySurface(EGLSurface surface) { DCHECK(IsValidSurface(surface)); gpu_scheduler_.reset(); + decoder_.reset(); + gl_surface_ = NULL; + gl_context_ = NULL; surface_.reset(); } @@ -152,8 +170,7 @@ EGLContext Display::CreateContext(EGLConfig config, gpu::Buffer buffer = command_buffer_->GetTransferBuffer(transfer_buffer_id_); DCHECK(buffer.ptr != NULL); bool share_resources = share_ctx != NULL; - using gpu::gles2::GLES2Implementation; - context_.reset(new GLES2Implementation( + context_.reset(new gpu::gles2::GLES2Implementation( gles2_cmd_helper_.get(), buffer.size, buffer.ptr, @@ -161,10 +178,8 @@ EGLContext Display::CreateContext(EGLConfig config, share_resources, true)); - context_->EnableFeatureCHROMIUM( - "pepper3d_allow_buffers_on_multiple_targets"); - context_->EnableFeatureCHROMIUM( - "pepper3d_support_fixed_attribs"); + context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets"); + context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs"); return context_.get(); } diff --git a/gpu/gles2_conform_support/egl/display.h b/gpu/gles2_conform_support/egl/display.h index 48f993c..19571b3 100644 --- a/gpu/gles2_conform_support/egl/display.h +++ b/gpu/gles2_conform_support/egl/display.h @@ -7,8 +7,14 @@ #include <EGL/egl.h> -#include "base/basictypes.h" #include "base/memory/scoped_ptr.h" +#include "gpu/command_buffer/client/gles2_cmd_helper.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/command_buffer/service/gpu_scheduler.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "ui/gfx/gl/gl_context.h" +#include "ui/gfx/gl/gl_surface.h" +#include "ui/gfx/native_widget_types.h" namespace gpu { class CommandBufferService; @@ -61,6 +67,9 @@ class Display { bool is_initialized_; scoped_ptr<gpu::CommandBufferService> command_buffer_; scoped_ptr<gpu::GpuScheduler> gpu_scheduler_; + scoped_ptr<gpu::gles2::GLES2Decoder> decoder_; + scoped_refptr<gfx::GLContext> gl_context_; + scoped_refptr<gfx::GLSurface> gl_surface_; scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper_; int32 transfer_buffer_id_; diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index b571fe1..dbb7cee 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -217,10 +217,7 @@ 'command_buffer/service/gl_utils.h', 'command_buffer/service/gpu_scheduler.h', 'command_buffer/service/gpu_scheduler.cc', - 'command_buffer/service/gpu_scheduler_linux.cc', - 'command_buffer/service/gpu_scheduler_mac.cc', 'command_buffer/service/gpu_scheduler_mock.h', - 'command_buffer/service/gpu_scheduler_win.cc', 'command_buffer/service/id_manager.h', 'command_buffer/service/id_manager.cc', 'command_buffer/service/mocks.h', @@ -333,20 +330,6 @@ ], }, { - 'target_name': 'gles2_demo_lib', - 'type': 'static_library', - 'dependencies': [ - 'command_buffer_client', - 'gles2_c_lib', - ], - 'sources': [ - 'command_buffer/client/gles2_demo_c.h', - 'command_buffer/client/gles2_demo_c.c', - 'command_buffer/client/gles2_demo_cc.h', - 'command_buffer/client/gles2_demo_cc.cc', - ], - }, - { 'target_name': 'gpu_ipc', 'type': 'static_library', 'dependencies': [ @@ -363,32 +346,4 @@ ], }, ], - 'conditions': [ - ['OS == "win"', - { - 'targets': [ - { - 'target_name': 'gles2_demo', - 'type': 'executable', - 'dependencies': [ - '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', - 'command_buffer_service', - 'gles2_demo_lib', - ], - 'sources': [ - 'command_buffer/client/gles2_demo.cc', - ], - 'msvs_settings': { - 'VCLinkerTool': { - # 0 == not set - # 1 == /SUBSYSTEM:CONSOLE - # 2 == /SUBSYSTEM:WINDOWS - 'SubSystem': '2', - }, - }, - }, - ], - }, - ], - ], } diff --git a/ui/gfx/gl/gl_surface.h b/ui/gfx/gl/gl_surface.h index 6e31418..a9117df 100644 --- a/ui/gfx/gl/gl_surface.h +++ b/ui/gfx/gl/gl_surface.h @@ -53,12 +53,10 @@ class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> { // Called after a context is made current with this surface. virtual void OnMakeCurrent(GLContext* context); -#if !defined(OS_MACOSX) // Create a GL surface that renders directly to a view. static scoped_refptr<GLSurface> CreateViewGLSurface( bool software, gfx::PluginWindowHandle window); -#endif // Create a GL surface used for offscreen rendering. static scoped_refptr<GLSurface> CreateOffscreenGLSurface( diff --git a/ui/gfx/gl/gl_surface_mac.cc b/ui/gfx/gl/gl_surface_mac.cc index 440db41..1a60be2 100644 --- a/ui/gfx/gl/gl_surface_mac.cc +++ b/ui/gfx/gl/gl_surface_mac.cc @@ -48,35 +48,11 @@ bool GLSurface::InitializeOneOff() { return true; } -// TODO(apatrick): support ViewGLSurface on mac. -#if 0 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( + bool software, gfx::PluginWindowHandle window) { - switch (GetGLImplementation()) { - case kGLImplementationOSMesaGL: { - scoped_refptr<GLSurface> surface( - new NativeViewGLSurfaceOSMesa(window)); - if (!surface->Initialize()) - return NULL; - - return surface; - } - case kGLImplementationDesktopGL: { - scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceCGL( - window)); - if (!surface->Initialize()) - return NULL; - - return surface; - } - case kGLImplementationMockGL: - return new GLSurfaceStub; - default: - NOTREACHED(); - return NULL; - } + return CreateOffscreenGLSurface(software, gfx::Size(1, 1)); } -#endif scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface( bool software, diff --git a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc index 833360a..38f3044 100644 --- a/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc +++ b/webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.cc @@ -31,7 +31,9 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" +#include "ui/gfx/gl/gl_context.h" #include "ui/gfx/gl/gl_share_group.h" +#include "ui/gfx/gl/gl_surface.h" #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" using gpu::Buffer; @@ -181,10 +183,13 @@ class GLInProcessContext : public base::SupportsWeakPtr<GLInProcessContext> { scoped_ptr<Callback0::Type> context_lost_callback_; uint32 parent_texture_id_; scoped_ptr<CommandBufferService> command_buffer_; - GpuScheduler* gpu_scheduler_; - GLES2CmdHelper* gles2_helper_; + scoped_ptr< ::gpu::GpuScheduler> gpu_scheduler_; + scoped_ptr< ::gpu::gles2::GLES2Decoder> decoder_; + scoped_refptr<gfx::GLContext> context_; + scoped_refptr<gfx::GLSurface> surface_; + scoped_ptr<GLES2CmdHelper> gles2_helper_; int32 transfer_buffer_id_; - GLES2Implementation* gles2_implementation_; + scoped_ptr<GLES2Implementation> gles2_implementation_; Error last_error_; DISALLOW_COPY_AND_ASSIGN(GLInProcessContext); @@ -307,7 +312,7 @@ void GLInProcessContext::SetContextLostCallback(Callback0::Type* callback) { bool GLInProcessContext::MakeCurrent(GLInProcessContext* context) { if (context) { - gles2::SetGLContext(context->gles2_implementation_); + gles2::SetGLContext(context->gles2_implementation_.get()); // Don't request latest error status from service. Just use the locally // cached information from the last flush. @@ -362,17 +367,14 @@ void GLInProcessContext::DisableShaderTranslation() { } GLES2Implementation* GLInProcessContext::GetImplementation() { - return gles2_implementation_; + return gles2_implementation_.get(); } GLInProcessContext::GLInProcessContext(GLInProcessContext* parent) : parent_(parent ? parent->AsWeakPtr() : base::WeakPtr<GLInProcessContext>()), parent_texture_id_(0), - gpu_scheduler_(NULL), - gles2_helper_(NULL), transfer_buffer_id_(-1), - gles2_implementation_(NULL), last_error_(SUCCESS) { } @@ -429,52 +431,59 @@ bool GLInProcessContext::Initialize(bool onscreen, } command_buffer_.reset(new CommandBufferService); - if (!command_buffer_->Initialize(kCommandBufferSize)) + if (!command_buffer_->Initialize(kCommandBufferSize)) { + LOG(ERROR) << "Could not initialize command buffer."; + Destroy(); return false; + } // TODO(gman): This needs to be true if this is Pepper. bool bind_generates_resource = false; - gpu_scheduler_ = GpuScheduler::Create( - command_buffer_.get(), - context_group ? - context_group->gpu_scheduler_->decoder()->GetContextGroup() : - new ::gpu::gles2::ContextGroup(bind_generates_resource)); - - if (onscreen) { - if (render_surface == gfx::kNullPluginWindow) { - LOG(ERROR) << "Invalid surface handle for onscreen context."; - command_buffer_.reset(); - } else { - if (!gpu_scheduler_->Initialize(render_surface, - gfx::Size(), - false, - ::gpu::gles2::DisallowedExtensions(), - allowed_extensions, - attribs, - share_group.get())) { - LOG(ERROR) << "Could not initialize GpuScheduler."; - command_buffer_.reset(); - } - } + decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group ? + context_group->decoder_->GetContextGroup() : + new ::gpu::gles2::ContextGroup(bind_generates_resource))); + + gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(), + decoder_.get(), + NULL)); + + decoder_->set_engine(gpu_scheduler_.get()); + + if (render_surface) { + surface_ = gfx::GLSurface::CreateViewGLSurface(false, render_surface); } else { - if (!gpu_scheduler_->Initialize(render_surface, - size, - false, - ::gpu::gles2::DisallowedExtensions(), - allowed_extensions, - attribs, - share_group.get())) { - LOG(ERROR) << "Could not initialize offscreen GpuScheduler."; - command_buffer_.reset(); - } + surface_ = gfx::GLSurface::CreateOffscreenGLSurface(false, + gfx::Size(1, 1)); + } + + if (!surface_.get()) { + LOG(ERROR) << "Could not create GLSurface."; + Destroy(); + return false; + } + + context_ = gfx::GLContext::CreateGLContext(share_group.get(), surface_.get()); + if (!context_.get()) { + LOG(ERROR) << "Could not create GLContext."; + Destroy(); + return false; } - if (!command_buffer_.get()) { + + if (!decoder_->Initialize(surface_.get(), + context_.get(), + size, + ::gpu::gles2::DisallowedExtensions(), + allowed_extensions, + attribs)) { + LOG(ERROR) << "Could not initialize decoder."; Destroy(); return false; } - if (!gpu_scheduler_->SetParent(parent_.get() ? parent_->gpu_scheduler_ : NULL, - parent_texture_id_)) { + if (!decoder_->SetParent( + parent_.get() ? parent_->decoder_.get() : NULL, + parent_texture_id_)) { + LOG(ERROR) << "Could not set parent."; Destroy(); return false; } @@ -483,7 +492,7 @@ bool GLInProcessContext::Initialize(bool onscreen, NewCallback(this, &GLInProcessContext::PumpCommands)); // Create the GLES2 helper, which writes the command buffer protocol. - gles2_helper_ = new GLES2CmdHelper(command_buffer_.get()); + gles2_helper_.reset(new GLES2CmdHelper(command_buffer_.get())); if (!gles2_helper_->Initialize(kCommandBufferSize)) { Destroy(); return false; @@ -507,13 +516,13 @@ bool GLInProcessContext::Initialize(bool onscreen, } // Create the object exposing the OpenGL API. - gles2_implementation_ = new GLES2Implementation( - gles2_helper_, + gles2_implementation_.reset(new GLES2Implementation( + gles2_helper_.get(), transfer_buffer.size, transfer_buffer.ptr, transfer_buffer_id_, true, - false); + false)); return true; } @@ -524,7 +533,7 @@ void GLInProcessContext::Destroy() { parent_texture_id_ = 0; } - if (gles2_implementation_) { + if (gles2_implementation_.get()) { // First flush the context to ensure that any pending frees of resources // are completed. Otherwise, if this context is part of a share group, // those resources might leak. Also, any remaining side effects of commands @@ -532,8 +541,7 @@ void GLInProcessContext::Destroy() { // share group. gles2_implementation_->Flush(); - delete gles2_implementation_; - gles2_implementation_ = NULL; + gles2_implementation_.reset(); } if (command_buffer_.get() && transfer_buffer_id_ != -1) { @@ -541,8 +549,7 @@ void GLInProcessContext::Destroy() { transfer_buffer_id_ = -1; } - delete gles2_helper_; - gles2_helper_ = NULL; + gles2_helper_.reset(); command_buffer_.reset(); } |