diff options
author | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 06:44:39 +0000 |
---|---|---|
committer | gman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-19 06:44:39 +0000 |
commit | a3ded6d49e31e7b03926e30ee04bdb74a622ca9a (patch) | |
tree | c785c8cac83b0e7c30e50dbd24ed650397c59adf | |
parent | 10156ef03d6985f8c0a9def13b02ad6fc3cee7f9 (diff) | |
download | chromium_src-a3ded6d49e31e7b03926e30ee04bdb74a622ca9a.zip chromium_src-a3ded6d49e31e7b03926e30ee04bdb74a622ca9a.tar.gz chromium_src-a3ded6d49e31e7b03926e30ee04bdb74a622ca9a.tar.bz2 |
Add Ability to pass in allowed extensions to GPU contexts.
Questions:
1) Is WebGraphicsContext3D only used for WebGL? Currently
this patch makes that assumption.
2) I started by adding const char* allowed_extensions to
a bunch of functions. Then, at the IPC level added
GPUInitParams. Should I use GPUInitParams everywhere?
3) Is the path for gpu_init_params.h ok?
TEST=unit tests, manually tested WebGL
BUG=none
Review URL: http://codereview.chromium.org/3775014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63026 0039d316-1c4b-4281-b951-d872f2087c98
34 files changed, 384 insertions, 231 deletions
diff --git a/chrome/common/gpu_create_command_buffer_config.h b/chrome/common/gpu_create_command_buffer_config.h new file mode 100644 index 0000000..8a2525f --- /dev/null +++ b/chrome/common/gpu_create_command_buffer_config.h @@ -0,0 +1,27 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_GPU_CREATE_COMMAND_BUFFER_CONFIG_H_ +#define CHROME_COMMON_GPU_CREATE_COMMAND_BUFFER_CONFIG_H_ +#pragma once + +#include <string> +#include <vector> + +// Parameters passed when initializing a GPU channel. +struct GPUCreateCommandBufferConfig { + GPUCreateCommandBufferConfig() { } + + GPUCreateCommandBufferConfig( + const std::string& _allowed_extensions, + const std::vector<int>& _attribs) + : allowed_extensions(_allowed_extensions), + attribs(_attribs) { + } + + std::string allowed_extensions; + std::vector<int> attribs; +}; + +#endif // CHROME_COMMON_GPU_CREATE_COMMAND_BUFFER_CONFIG_H_ diff --git a/chrome/common/gpu_messages.cc b/chrome/common/gpu_messages.cc index 893f8c9..db7f597 100644 --- a/chrome/common/gpu_messages.cc +++ b/chrome/common/gpu_messages.cc @@ -4,6 +4,7 @@ #include "chrome/common/gpu_messages.h" +#include "chrome/common/gpu_create_command_buffer_config.h" #include "chrome/common/gpu_info.h" #include "chrome/common/dx_diag_node.h" #include "gfx/rect.h" @@ -185,4 +186,24 @@ void ParamTraits<gpu::CommandBuffer::State> ::Log(const param_type& p, l->append("<CommandBuffer::State>"); } -} // namespace IPC +void ParamTraits<GPUCreateCommandBufferConfig> ::Write( + Message* m, const param_type& p) { + m->WriteString(p.allowed_extensions); + ParamTraits<std::vector<int> > ::Write(m, p.attribs); +} + +bool ParamTraits<GPUCreateCommandBufferConfig> ::Read( + const Message* m, void** iter, param_type* p) { + if (!m->ReadString(iter, &p->allowed_extensions) || + !ParamTraits<std::vector<int> > ::Read(m, iter, &p->attribs)) { + return false; + } + return true; +} + +void ParamTraits<GPUCreateCommandBufferConfig> ::Log( + const param_type& p, std::string* l) { + l->append("<GPUCreateCommandBufferConfig>"); +} + +} // namespace IPC diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h index b95a534..184d8f4 100644 --- a/chrome/common/gpu_messages_internal.h +++ b/chrome/common/gpu_messages_internal.h @@ -10,6 +10,7 @@ // from it via utility_messages.h. #include <vector> +#include <string> #include "base/shared_memory.h" #include "chrome/common/gpu_video_common.h" @@ -23,6 +24,7 @@ namespace IPC { struct ChannelHandle; } +struct GPUCreateCommandBufferConfig; class GPUInfo; //------------------------------------------------------------------------------ @@ -157,9 +159,10 @@ IPC_BEGIN_MESSAGES(GpuChannel) // to a native view. The |render_view_id| is currently needed only on Mac OS // X in order to identify the window on the browser side into which the // rendering results go. A corresponding GpuCommandBufferStub is created. - IPC_SYNC_MESSAGE_CONTROL2_1(GpuChannelMsg_CreateViewCommandBuffer, + IPC_SYNC_MESSAGE_CONTROL3_1(GpuChannelMsg_CreateViewCommandBuffer, gfx::NativeViewId, /* view */ int32, /* render_view_id */ + GPUCreateCommandBufferConfig, /* init_params */ int32 /* route_id */) // Tells the GPU process to create a new command buffer that renders to an @@ -170,7 +173,7 @@ IPC_BEGIN_MESSAGES(GpuChannel) IPC_SYNC_MESSAGE_CONTROL4_1(GpuChannelMsg_CreateOffscreenCommandBuffer, int32, /* parent_route_id */ gfx::Size, /* size */ - std::vector<int>, /* attribs */ + GPUCreateCommandBufferConfig, /* init_params */ uint32, /* parent_texture_id */ int32 /* route_id */) diff --git a/chrome/common/gpu_param_traits.h b/chrome/common/gpu_param_traits.h index f2c4e02..59885ea 100644 --- a/chrome/common/gpu_param_traits.h +++ b/chrome/common/gpu_param_traits.h @@ -10,6 +10,7 @@ #include "base/process.h" #include "chrome/common/common_param_traits.h" #include "chrome/common/dx_diag_node.h" +#include "chrome/common/gpu_create_command_buffer_config.h" #include "chrome/common/gpu_info.h" #include "chrome/common/gpu_native_window_handle.h" #include "gfx/native_widget_types.h" @@ -67,6 +68,15 @@ struct ParamTraits<gpu::CommandBuffer::State> { static bool Read(const Message* m, void** iter, param_type* p); static void Log(const param_type& p, std::string* l); }; + +template <> +struct ParamTraits<GPUCreateCommandBufferConfig> { + typedef GPUCreateCommandBufferConfig param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* p); + static void Log(const param_type& p, std::string* l); +}; + } // namespace IPC #endif // CHROME_COMMON_GPU_PARAM_TRAITS_H_ diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc index fc2c09c..1ff2598 100644 --- a/chrome/gpu/gpu_channel.cc +++ b/chrome/gpu/gpu_channel.cc @@ -102,9 +102,11 @@ int GpuChannel::GenerateRouteID() { return ++last_id; } -void GpuChannel::OnCreateViewCommandBuffer(gfx::NativeViewId view_id, - int32 render_view_id, - int32* route_id) { +void GpuChannel::OnCreateViewCommandBuffer( + gfx::NativeViewId view_id, + int32 render_view_id, + const GPUCreateCommandBufferConfig& init_params, + int32* route_id) { *route_id = 0; #if defined(ENABLE_GPU) @@ -143,11 +145,9 @@ void GpuChannel::OnCreateViewCommandBuffer(gfx::NativeViewId view_id, #endif *route_id = GenerateRouteID(); - // TODO(enne): implement context creation attributes for view buffers - std::vector<int32> attribs; scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub( - this, handle, NULL, gfx::Size(), attribs, 0, *route_id, - renderer_id_, render_view_id)); + this, handle, NULL, gfx::Size(), init_params.allowed_extensions, + init_params.attribs, 0, *route_id, renderer_id_, render_view_id)); router_.AddRoute(*route_id, stub.get()); stubs_.AddWithID(stub.release(), *route_id); #endif // ENABLE_GPU @@ -156,7 +156,7 @@ void GpuChannel::OnCreateViewCommandBuffer(gfx::NativeViewId view_id, void GpuChannel::OnCreateOffscreenCommandBuffer( int32 parent_route_id, const gfx::Size& size, - const std::vector<int32>& attribs, + const GPUCreateCommandBufferConfig& init_params, uint32 parent_texture_id, int32* route_id) { #if defined(ENABLE_GPU) @@ -170,7 +170,8 @@ void GpuChannel::OnCreateOffscreenCommandBuffer( gfx::kNullPluginWindow, parent_stub, size, - attribs, + init_params.allowed_extensions, + init_params.attribs, parent_texture_id, *route_id, 0, 0)); diff --git a/chrome/gpu/gpu_channel.h b/chrome/gpu/gpu_channel.h index e7cb1db..f359777 100644 --- a/chrome/gpu/gpu_channel.h +++ b/chrome/gpu/gpu_channel.h @@ -13,6 +13,7 @@ #include "base/scoped_open_process.h" #include "base/scoped_ptr.h" #include "build/build_config.h" +#include "chrome/common/gpu_create_command_buffer_config.h" #include "chrome/common/gpu_video_common.h" #include "chrome/common/message_router.h" #include "chrome/gpu/gpu_command_buffer_stub.h" @@ -65,14 +66,17 @@ class GpuChannel : public IPC::Channel::Listener, int GenerateRouteID(); // Message handlers. - void OnCreateViewCommandBuffer(gfx::NativeViewId view, - int32 render_view_id, - int32* route_id); - void OnCreateOffscreenCommandBuffer(int32 parent_route_id, - const gfx::Size& size, - const std::vector<int32>& attribs, - uint32 parent_texture_id, - int32* route_id); + void OnCreateViewCommandBuffer( + gfx::NativeViewId view, + int32 render_view_id, + const GPUCreateCommandBufferConfig& init_params, + int32* route_id); + void OnCreateOffscreenCommandBuffer( + int32 parent_route_id, + const gfx::Size& size, + const GPUCreateCommandBufferConfig& init_params, + uint32 parent_texture_id, + int32* route_id); void OnDestroyCommandBuffer(int32 route_id); void OnCreateVideoDecoder(int32 context_route_id, diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc index 040dcef..f6118fa 100644 --- a/chrome/gpu/gpu_command_buffer_stub.cc +++ b/chrome/gpu/gpu_command_buffer_stub.cc @@ -14,15 +14,17 @@ using gpu::Buffer; -GpuCommandBufferStub::GpuCommandBufferStub(GpuChannel* channel, - gfx::PluginWindowHandle handle, - GpuCommandBufferStub* parent, - const gfx::Size& size, - const std::vector<int32>& attribs, - uint32 parent_texture_id, - int32 route_id, - int32 renderer_id, - int32 render_view_id) +GpuCommandBufferStub::GpuCommandBufferStub( + GpuChannel* channel, + gfx::PluginWindowHandle handle, + GpuCommandBufferStub* parent, + const gfx::Size& size, + const std::string& allowed_extensions, + const std::vector<int32>& attribs, + uint32 parent_texture_id, + int32 route_id, + int32 renderer_id, + int32 render_view_id) : channel_(channel), handle_(handle), parent_( @@ -82,10 +84,11 @@ void GpuCommandBufferStub::OnInitialize( if (buffer.shared_memory) { gpu::GPUProcessor* parent_processor = parent_ ? parent_->processor_.get() : NULL; - processor_.reset(new gpu::GPUProcessor(command_buffer_.get())); + processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL)); if (processor_->Initialize( handle_, initial_size_, + allowed_extensions_.c_str(), requested_attribs_, parent_processor, parent_texture_id_)) { diff --git a/chrome/gpu/gpu_command_buffer_stub.h b/chrome/gpu/gpu_command_buffer_stub.h index f217469..fe8b743 100644 --- a/chrome/gpu/gpu_command_buffer_stub.h +++ b/chrome/gpu/gpu_command_buffer_stub.h @@ -9,6 +9,7 @@ #if defined(ENABLE_GPU) #include <vector> +#include <string> #include "base/process.h" #include "base/weak_ptr.h" @@ -30,6 +31,7 @@ class GpuCommandBufferStub gfx::PluginWindowHandle handle, GpuCommandBufferStub* parent, const gfx::Size& size, + const std::string& allowed_extensions, const std::vector<int32>& attribs, uint32 parent_texture_id, int32 route_id, @@ -78,6 +80,7 @@ class GpuCommandBufferStub gfx::PluginWindowHandle handle_; base::WeakPtr<GpuCommandBufferStub> parent_; gfx::Size initial_size_; + std::string allowed_extensions_; std::vector<int32> requested_attribs_; uint32 parent_texture_id_; int32 route_id_; diff --git a/chrome/gpu/gpu_video_decoder_unittest.cc b/chrome/gpu/gpu_video_decoder_unittest.cc index 893d07b..30f1664 100644 --- a/chrome/gpu/gpu_video_decoder_unittest.cc +++ b/chrome/gpu/gpu_video_decoder_unittest.cc @@ -5,7 +5,6 @@ #include "base/process.h" #include "chrome/common/gpu_messages.h" #include "chrome/gpu/gpu_video_decoder.h" -#include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" #include "ipc/ipc_message_utils.h" #include "media/video/mock_objects.h" @@ -70,7 +69,7 @@ class GpuVideoDecoderTest : public testing::Test, public: GpuVideoDecoderTest() { // Create the mock objects. - gles2_decoder_.reset(new gpu::gles2::MockGLES2Decoder(&group_)); + gles2_decoder_.reset(new gpu::gles2::MockGLES2Decoder()); gpu_video_decoder_ = new GpuVideoDecoder( &message_loop_, kDecoderHostId, this, base::kNullProcessHandle, @@ -227,7 +226,6 @@ class GpuVideoDecoderTest : public testing::Test, scoped_refptr<GpuVideoDecoder> gpu_video_decoder_; MockGpuVideoDevice* mock_device_; media::MockVideoDecodeEngine* mock_engine_; - gpu::gles2::ContextGroup group_; scoped_ptr<gpu::gles2::MockGLES2Decoder> gles2_decoder_; std::vector<scoped_refptr<media::VideoFrame> > decoder_frames_; scoped_refptr<media::VideoFrame> device_frame_; diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc index 7f699ba..77f8e13 100644 --- a/chrome/plugin/command_buffer_stub.cc +++ b/chrome/plugin/command_buffer_stub.cc @@ -92,8 +92,8 @@ void CommandBufferStub::OnInitialize(int32 size, } // Initialize the GPUProcessor. - processor_.reset(new gpu::GPUProcessor(command_buffer_.get())); - if (!processor_->Initialize(window_, gfx::Size(), std::vector<int32>(), + processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL)); + if (!processor_->Initialize(window_, gfx::Size(), NULL, std::vector<int32>(), NULL, 0)) { Destroy(); return; diff --git a/chrome/renderer/ggl/ggl.cc b/chrome/renderer/ggl/ggl.cc index f69e3c3..0589852 100644 --- a/chrome/renderer/ggl/ggl.cc +++ b/chrome/renderer/ggl/ggl.cc @@ -64,6 +64,7 @@ class Context : public base::SupportsWeakPtr<Context> { bool Initialize(gfx::NativeViewId view, int render_view_id, const gfx::Size& size, + const char* allowed_extensions, const int32* attrib_list); #if defined(OS_MACOSX) @@ -151,6 +152,7 @@ Context::~Context() { bool Context::Initialize(gfx::NativeViewId view, int render_view_id, const gfx::Size& size, + const char* allowed_extensions, const int32* attrib_list) { DCHECK(size.width() >= 0 && size.height() >= 0); @@ -199,15 +201,18 @@ bool Context::Initialize(gfx::NativeViewId view, // Create a proxy to a command buffer in the GPU process. if (view) { - // TODO(enne): this call should also handle attribs - command_buffer_ = - channel_->CreateViewCommandBuffer(view, render_view_id); + command_buffer_ = channel_->CreateViewCommandBuffer( + view, + render_view_id, + allowed_extensions, + attribs); } else { CommandBufferProxy* parent_command_buffer = parent_.get() ? parent_->command_buffer_ : NULL; command_buffer_ = channel_->CreateOffscreenCommandBuffer( parent_command_buffer, size, + allowed_extensions, attribs, parent_texture_id_); } @@ -408,10 +413,12 @@ void Context::OnSwapBuffers() { Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view, int render_view_id, + const char* allowed_extensions, const int32* attrib_list) { #if defined(ENABLE_GPU) scoped_ptr<Context> context(new Context(channel, NULL)); - if (!context->Initialize(view, render_view_id, gfx::Size(), attrib_list)) + if (!context->Initialize( + view, render_view_id, gfx::Size(), allowed_extensions, attrib_list)) return NULL; return context.release(); @@ -431,10 +438,11 @@ void ResizeOnscreenContext(Context* context, const gfx::Size& size) { Context* CreateOffscreenContext(GpuChannelHost* channel, Context* parent, const gfx::Size& size, + const char* allowed_extensions, const int32* attrib_list) { #if defined(ENABLE_GPU) scoped_ptr<Context> context(new Context(channel, parent)); - if (!context->Initialize(0, 0, size, attrib_list)) + if (!context->Initialize(0, 0, size, allowed_extensions, attrib_list)) return NULL; return context.release(); diff --git a/chrome/renderer/ggl/ggl.h b/chrome/renderer/ggl/ggl.h index b535306..1d53f57 100644 --- a/chrome/renderer/ggl/ggl.h +++ b/chrome/renderer/ggl/ggl.h @@ -19,10 +19,8 @@ class GpuChannelHost; class MessageLoop; namespace media { - class VideoDecodeContext; class VideoDecodeEngine; - } namespace ggl { @@ -78,6 +76,7 @@ bool Terminate(); Context* CreateViewContext(GpuChannelHost* channel, gfx::NativeViewId view, int render_view_id, + const char* allowed_extensions, const int32* attrib_list); #if defined(OS_MACOSX) @@ -97,6 +96,7 @@ void ResizeOnscreenContext(Context* context, const gfx::Size& size); Context* CreateOffscreenContext(GpuChannelHost* channel, Context* parent, const gfx::Size& size, + const char* allowed_extensions, const int32* attrib_list); // Resize an offscreen frame buffer. The resize occurs on the next call to diff --git a/chrome/renderer/gpu_channel_host.cc b/chrome/renderer/gpu_channel_host.cc index de89774..0532d2e 100644 --- a/chrome/renderer/gpu_channel_host.cc +++ b/chrome/renderer/gpu_channel_host.cc @@ -5,6 +5,7 @@ #include "chrome/renderer/gpu_channel_host.h" #include "chrome/common/child_process.h" +#include "chrome/common/gpu_create_command_buffer_config.h" #include "chrome/common/gpu_messages.h" #include "chrome/renderer/command_buffer_proxy.h" #include "chrome/renderer/gpu_video_service_host.h" @@ -84,16 +85,22 @@ bool GpuChannelHost::Send(IPC::Message* message) { } CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer( - gfx::NativeViewId view, int render_view_id) { + gfx::NativeViewId view, + int render_view_id, + const std::string& allowed_extensions, + const std::vector<int32>& attribs) { #if defined(ENABLE_GPU) // An error occurred. Need to get the host again to reinitialize it. if (!channel_.get()) return NULL; + GPUCreateCommandBufferConfig init_params(allowed_extensions, attribs); int32 route_id; - if (!Send(new GpuChannelMsg_CreateViewCommandBuffer(view, - render_view_id, - &route_id)) && + if (!Send(new GpuChannelMsg_CreateViewCommandBuffer( + view, + render_view_id, + init_params, + &route_id)) && route_id != MSG_ROUTING_NONE) { return NULL; } @@ -110,6 +117,7 @@ CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer( CommandBufferProxy* GpuChannelHost::CreateOffscreenCommandBuffer( CommandBufferProxy* parent, const gfx::Size& size, + const std::string& allowed_extensions, const std::vector<int32>& attribs, uint32 parent_texture_id) { #if defined(ENABLE_GPU) @@ -117,11 +125,12 @@ CommandBufferProxy* GpuChannelHost::CreateOffscreenCommandBuffer( if (!channel_.get()) return NULL; + GPUCreateCommandBufferConfig init_params(allowed_extensions, attribs); int32 parent_route_id = parent ? parent->route_id() : 0; int32 route_id; if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(parent_route_id, size, - attribs, + init_params, parent_texture_id, &route_id)) && route_id != MSG_ROUTING_NONE) { diff --git a/chrome/renderer/gpu_channel_host.h b/chrome/renderer/gpu_channel_host.h index e6eecea..75152ba 100644 --- a/chrome/renderer/gpu_channel_host.h +++ b/chrome/renderer/gpu_channel_host.h @@ -60,13 +60,17 @@ class GpuChannelHost : public IPC::Channel::Listener, virtual bool Send(IPC::Message* msg); // Create and connect to a command buffer in the GPU process. - CommandBufferProxy* CreateViewCommandBuffer(gfx::NativeViewId view, - int render_view_id); + CommandBufferProxy* CreateViewCommandBuffer( + gfx::NativeViewId view, + int render_view_id, + const std::string& allowed_extensions, + const std::vector<int32>& attribs); // Create and connect to a command buffer in the GPU process. CommandBufferProxy* CreateOffscreenCommandBuffer( CommandBufferProxy* parent, const gfx::Size& size, + const std::string& allowed_extensions, const std::vector<int32>& attribs, uint32 parent_texture_id); diff --git a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc index 8254c290..67e26c7 100644 --- a/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc +++ b/chrome/renderer/webgraphicscontext3d_command_buffer_impl.cc @@ -54,6 +54,11 @@ WebGraphicsContext3DCommandBufferImpl:: } } +static const char* kWebGraphicsContext3DPerferredGLExtensions = + "GL_EXT_packed_depth_stencil " + "GL_OES_packed_depth_stencil " + "GL_OES_depth24"; + bool WebGraphicsContext3DCommandBufferImpl::initialize( WebGraphicsContext3D::Attributes attributes, WebKit::WebView* web_view, @@ -98,6 +103,7 @@ bool WebGraphicsContext3DCommandBufferImpl::initialize( host, view_id, renderview->routing_id(), + kWebGraphicsContext3DPerferredGLExtensions, attribs); } else { bool compositing_enabled = !CommandLine::ForCurrentProcess()->HasSwitch( @@ -117,10 +123,12 @@ bool WebGraphicsContext3DCommandBufferImpl::initialize( parent_context = context_impl->context_; } } - context_ = ggl::CreateOffscreenContext(host, - parent_context, - gfx::Size(1, 1), - attribs); + context_ = ggl::CreateOffscreenContext( + host, + parent_context, + gfx::Size(1, 1), + kWebGraphicsContext3DPerferredGLExtensions, + attribs); web_view_ = NULL; } if (!context_) diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc index 9224866..05c0003 100644 --- a/gpu/command_buffer/client/gles2_demo.cc +++ b/gpu/command_buffer/client/gles2_demo.cc @@ -56,9 +56,10 @@ bool GLES2Demo::Setup(void* hwnd, int32 size) { if (!command_buffer->Initialize(size)) return NULL; - GPUProcessor* gpu_processor = new GPUProcessor(command_buffer.get()); + GPUProcessor* gpu_processor = new GPUProcessor(command_buffer.get(), NULL); if (!gpu_processor->Initialize(reinterpret_cast<HWND>(hwnd), gfx::Size(), + NULL, std::vector<int32>(), NULL, 0)) { diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc index c2c9c1f..07583c0 100644 --- a/gpu/command_buffer/service/context_group.cc +++ b/gpu/command_buffer/service/context_group.cc @@ -18,6 +18,7 @@ namespace gles2 { ContextGroup::ContextGroup() : initialized_(false), + have_context_(true), max_vertex_attribs_(0u), max_texture_units_(0u), max_texture_image_units_(0u), @@ -28,13 +29,7 @@ ContextGroup::ContextGroup() } ContextGroup::~ContextGroup() { - // Check that Destroy has been called. - DCHECK(buffer_manager_ == NULL); - DCHECK(framebuffer_manager_ == NULL); - DCHECK(renderbuffer_manager_ == NULL); - DCHECK(texture_manager_ == NULL); - DCHECK(program_manager_ == NULL); - DCHECK(shader_manager_ == NULL); + Destroy(); } static void GetIntegerv(GLenum pname, uint32* var) { @@ -43,8 +38,6 @@ static void GetIntegerv(GLenum pname, uint32* var) { *var = value; } - - bool ContextGroup::Initialize(const char* allowed_features) { if (initialized_) { return true; @@ -115,34 +108,34 @@ bool ContextGroup::Initialize(const char* allowed_features) { return true; } -void ContextGroup::Destroy(bool have_context) { +void ContextGroup::Destroy() { if (buffer_manager_ != NULL) { - buffer_manager_->Destroy(have_context); + buffer_manager_->Destroy(have_context_); buffer_manager_.reset(); } if (framebuffer_manager_ != NULL) { - framebuffer_manager_->Destroy(have_context); + framebuffer_manager_->Destroy(have_context_); framebuffer_manager_.reset(); } if (renderbuffer_manager_ != NULL) { - renderbuffer_manager_->Destroy(have_context); + renderbuffer_manager_->Destroy(have_context_); renderbuffer_manager_.reset(); } if (texture_manager_ != NULL) { - texture_manager_->Destroy(have_context); + texture_manager_->Destroy(have_context_); texture_manager_.reset(); } if (program_manager_ != NULL) { - program_manager_->Destroy(have_context); + program_manager_->Destroy(have_context_); program_manager_.reset(); } if (shader_manager_ != NULL) { - shader_manager_->Destroy(have_context); + shader_manager_->Destroy(have_context_); shader_manager_.reset(); } } diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h index 4df515c..9d0efd4 100644 --- a/gpu/command_buffer/service/context_group.h +++ b/gpu/command_buffer/service/context_group.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "base/linked_ptr.h" #include "base/scoped_ptr.h" +#include "base/ref_counted.h" #include "gpu/command_buffer/service/gles2_cmd_validation.h" #include "gpu/command_buffer/service/feature_info.h" @@ -29,16 +30,20 @@ class TextureManager; // A Context Group helps manage multiple GLES2Decoders that share // resources. -class ContextGroup { +class ContextGroup : public base::RefCounted<ContextGroup> { public: + typedef scoped_refptr<ContextGroup> Ref; + ContextGroup(); ~ContextGroup(); // This should only be called by GLES2Decoder. bool Initialize(const char* allowed_features); - // Destroys all the resources. MUST be called before destruction. - void Destroy(bool have_context); + // Sets the ContextGroup has having a lost context. + void SetLostContext() { + have_context_ = false; + } uint32 max_vertex_attribs() const { return max_vertex_attribs_; @@ -99,8 +104,12 @@ class ContextGroup { IdAllocator* GetIdAllocator(unsigned namepsace_id); private: + // Destroys all the resources. + void Destroy(); + // Whether or not this context is initialized. bool initialized_; + bool have_context_; uint32 max_vertex_attribs_; uint32 max_texture_units_; diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc index c5c57a1..006cfe3 100644 --- a/gpu/command_buffer/service/context_group_unittest.cc +++ b/gpu/command_buffer/service/context_group_unittest.cc @@ -37,58 +37,62 @@ class ContextGroupTest : public testing::Test { virtual void SetUp() { gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>()); ::gfx::GLInterface::SetGLInterface(gl_.get()); + group_ = ContextGroup::Ref(new ContextGroup()); } virtual void TearDown() { - group_.Destroy(false); + // we must release the ContextGroup before we clear out the GL interface. + // since its destructor uses GL. + group_->SetLostContext(); + group_ = NULL; ::gfx::GLInterface::SetGLInterface(NULL); gl_.reset(); } scoped_ptr< ::testing::StrictMock< ::gfx::MockGLInterface> > gl_; - ContextGroup group_; + ContextGroup::Ref group_; }; TEST_F(ContextGroupTest, Basic) { // Test it starts off uninitialized. - EXPECT_EQ(0u, group_.max_vertex_attribs()); - EXPECT_EQ(0u, group_.max_texture_units()); - EXPECT_EQ(0u, group_.max_texture_image_units()); - EXPECT_EQ(0u, group_.max_vertex_texture_image_units()); - EXPECT_EQ(0u, group_.max_fragment_uniform_vectors()); - EXPECT_EQ(0u, group_.max_varying_vectors()); - EXPECT_EQ(0u, group_.max_vertex_uniform_vectors()); - EXPECT_TRUE(group_.buffer_manager() == NULL); - EXPECT_TRUE(group_.framebuffer_manager() == NULL); - EXPECT_TRUE(group_.renderbuffer_manager() == NULL); - EXPECT_TRUE(group_.texture_manager() == NULL); - EXPECT_TRUE(group_.program_manager() == NULL); - EXPECT_TRUE(group_.shader_manager() == NULL); + EXPECT_EQ(0u, group_->max_vertex_attribs()); + EXPECT_EQ(0u, group_->max_texture_units()); + EXPECT_EQ(0u, group_->max_texture_image_units()); + EXPECT_EQ(0u, group_->max_vertex_texture_image_units()); + EXPECT_EQ(0u, group_->max_fragment_uniform_vectors()); + EXPECT_EQ(0u, group_->max_varying_vectors()); + EXPECT_EQ(0u, group_->max_vertex_uniform_vectors()); + EXPECT_TRUE(group_->buffer_manager() == NULL); + EXPECT_TRUE(group_->framebuffer_manager() == NULL); + EXPECT_TRUE(group_->renderbuffer_manager() == NULL); + EXPECT_TRUE(group_->texture_manager() == NULL); + EXPECT_TRUE(group_->program_manager() == NULL); + EXPECT_TRUE(group_->shader_manager() == NULL); } TEST_F(ContextGroupTest, InitializeNoExtensions) { TestHelper::SetupContextGroupInitExpectations(gl_.get(), ""); - group_.Initialize(""); + group_->Initialize(""); EXPECT_EQ(static_cast<uint32>(TestHelper::kNumVertexAttribs), - group_.max_vertex_attribs()); + group_->max_vertex_attribs()); EXPECT_EQ(static_cast<uint32>(TestHelper::kNumTextureUnits), - group_.max_texture_units()); + group_->max_texture_units()); EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxTextureImageUnits), - group_.max_texture_image_units()); + group_->max_texture_image_units()); EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxVertexTextureImageUnits), - group_.max_vertex_texture_image_units()); + group_->max_vertex_texture_image_units()); EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxFragmentUniformVectors), - group_.max_fragment_uniform_vectors()); + group_->max_fragment_uniform_vectors()); EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxVaryingVectors), - group_.max_varying_vectors()); + group_->max_varying_vectors()); EXPECT_EQ(static_cast<uint32>(TestHelper::kMaxVertexUniformVectors), - group_.max_vertex_uniform_vectors()); - EXPECT_TRUE(group_.buffer_manager() != NULL); - EXPECT_TRUE(group_.framebuffer_manager() != NULL); - EXPECT_TRUE(group_.renderbuffer_manager() != NULL); - EXPECT_TRUE(group_.texture_manager() != NULL); - EXPECT_TRUE(group_.program_manager() != NULL); - EXPECT_TRUE(group_.shader_manager() != NULL); + group_->max_vertex_uniform_vectors()); + EXPECT_TRUE(group_->buffer_manager() != NULL); + EXPECT_TRUE(group_->framebuffer_manager() != NULL); + EXPECT_TRUE(group_->renderbuffer_manager() != NULL); + EXPECT_TRUE(group_->texture_manager() != NULL); + EXPECT_TRUE(group_->program_manager() != NULL); + EXPECT_TRUE(group_->shader_manager() != NULL); } } // namespace gles2 diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 883dcd0..fa835ef 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -18,41 +18,64 @@ FeatureInfo::FeatureInfo() { // Helps query for extensions. class ExtensionHelper { public: - ExtensionHelper(const char* extensions, const char* allowed_features) { - std::set<std::string> sets[2]; - - for (int ii = 0; ii < 2; ++ii) { - const char* s = (ii == 0 ? extensions : allowed_features); - std::string str(s ? s : ""); - std::string::size_type lastPos = 0; - while (true) { - std::string::size_type pos = str.find_first_of(" ", lastPos); - if (pos != std::string::npos) { - sets[ii].insert(str.substr(lastPos, pos - lastPos)); - lastPos = pos + 1; - } else { - sets[ii].insert(str.substr(lastPos)); - break; - } - } + ExtensionHelper(const char* extensions, const char* desired_features) + : desire_all_features_(false) { + // Check for "*" + if (desired_features && + desired_features[0] == '*' && + desired_features[1] == '\0') { + desired_features = NULL; } - if (allowed_features) { - std::set_intersection( - sets[0].begin(), sets[0].end(), sets[1].begin(), sets[1].end(), - std::inserter(extensions_, extensions_.begin())); - } else { - extensions_ = sets[0]; - } + InitStringSet(extensions, &have_extensions_); + InitStringSet(desired_features, &desired_extensions_); + + if (!desired_features) { + desire_all_features_ = true; + } } // Returns true if extension exists. - bool HasExtension(const char* extension) { - return extensions_.find(extension) != extensions_.end(); + bool Have(const char* extension) { + return have_extensions_.find(extension) != have_extensions_.end(); + } + + // Returns true of an extension is desired. It may not exist. + bool Desire(const char* extension) { + return desire_all_features_ || + desired_extensions_.find(extension) != desired_extensions_.end(); + } + + // Returns true if an extension exists and is desired. + bool HaveAndDesire(const char* extension) { + return Have(extension) && Desire(extension); } private: - std::set<std::string> extensions_; + void InitStringSet(const char* s, std::set<std::string>* string_set) { + std::string str(s ? s : ""); + std::string::size_type lastPos = 0; + while (true) { + std::string::size_type pos = str.find_first_of(" ", lastPos); + if (pos != std::string::npos) { + if (pos - lastPos) { + string_set->insert(str.substr(lastPos, pos - lastPos)); + } + lastPos = pos + 1; + } else { + string_set->insert(str.substr(lastPos)); + break; + } + } + } + + bool desire_all_features_; + + // Extensions that exist. + std::set<std::string> have_extensions_; + + // Extensions that are desired but may not exist. + std::set<std::string> desired_extensions_; }; bool FeatureInfo::Initialize(const char* allowed_features) { @@ -62,17 +85,13 @@ bool FeatureInfo::Initialize(const char* allowed_features) { void FeatureInfo::AddFeatures(const char* desired_features) { // Figure out what extensions to turn on. - std::string gl_extensions( - reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS))); - - ExtensionHelper helper( - (gl_extensions + - (gl_extensions.empty() ? "" : " ") + "GL_CHROMIUM_map_sub").c_str(), + ExtensionHelper ext( + reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)), desired_features); bool npot_ok = false; - if (helper.HasExtension("GL_CHROMIUM_map_sub")) { + if (ext.Desire("GL_CHROMIUM_map_sub")) { AddExtensionString("GL_CHROMIUM_map_sub"); } @@ -81,10 +100,10 @@ void FeatureInfo::AddFeatures(const char* desired_features) { bool enable_dxt1 = false; bool enable_s3tc = false; - if (helper.HasExtension("GL_EXT_texture_compression_dxt1")) { + if (ext.HaveAndDesire("GL_EXT_texture_compression_dxt1")) { enable_dxt1 = true; } - if (helper.HasExtension("GL_EXT_texture_compression_s3tc")) { + if (ext.HaveAndDesire("GL_EXT_texture_compression_s3tc")) { enable_dxt1 = true; enable_s3tc = true; } @@ -106,7 +125,7 @@ void FeatureInfo::AddFeatures(const char* desired_features) { } // Check if we should enable GL_EXT_texture_filter_anisotropic. - if (helper.HasExtension("GL_EXT_texture_filter_anisotropic")) { + if (ext.HaveAndDesire("GL_EXT_texture_filter_anisotropic")) { AddExtensionString("GL_EXT_texture_filter_anisotropic"); validators_.texture_parameter.AddValue( GL_TEXTURE_MAX_ANISOTROPY_EXT); @@ -121,8 +140,9 @@ void FeatureInfo::AddFeatures(const char* desired_features) { // GL_OES_packed_depth_stencil does not provide. Therefore we made up // GL_GOOGLE_depth_texture. bool enable_depth_texture = false; - if (helper.HasExtension("GL_ARB_depth_texture") || - helper.HasExtension("GL_OES_depth_texture")) { + if (ext.Desire("GL_GOOGLE_depth_texture") && + (ext.Have("GL_ARB_depth_texture") || + ext.Have("GL_OES_depth_texture"))) { enable_depth_texture = true; AddExtensionString("GL_GOOGLE_depth_texture"); validators_.texture_internal_format.AddValue(GL_DEPTH_COMPONENT); @@ -132,8 +152,9 @@ void FeatureInfo::AddFeatures(const char* desired_features) { } // TODO(gman): Add depth types fo ElementsPerGroup and BytesPerElement - if (helper.HasExtension("GL_EXT_packed_depth_stencil") || - helper.HasExtension("GL_OES_packed_depth_stencil")) { + if (ext.Desire("GL_OES_packed_depth_stencil") && + (ext.Have("GL_EXT_packed_depth_stencil") || + ext.Have("GL_OES_packed_depth_stencil"))) { AddExtensionString("GL_OES_packed_depth_stencil"); if (enable_depth_texture) { validators_.texture_internal_format.AddValue(GL_DEPTH_STENCIL); @@ -146,17 +167,18 @@ void FeatureInfo::AddFeatures(const char* desired_features) { bool enable_texture_format_bgra8888 = false; bool enable_read_format_bgra = false; // Check if we should allow GL_EXT_texture_format_BGRA8888 - if (helper.HasExtension("GL_EXT_texture_format_BGRA8888") || - helper.HasExtension("GL_APPLE_texture_format_BGRA8888")) { + if (ext.Desire("GL_EXT_texture_format_BGRA8888") && + (ext.Have("GL_EXT_texture_format_BGRA8888") || + ext.Have("GL_APPLE_texture_format_BGRA8888"))) { enable_texture_format_bgra8888 = true; } - if (helper.HasExtension("GL_EXT_bgra")) { + if (ext.HaveAndDesire("GL_EXT_bgra")) { enable_texture_format_bgra8888 = true; enable_read_format_bgra = true; } - if (helper.HasExtension("GL_EXT_read_format_bgra")) { + if (ext.HaveAndDesire("GL_EXT_read_format_bgra")) { enable_read_format_bgra = true; } @@ -172,8 +194,9 @@ void FeatureInfo::AddFeatures(const char* desired_features) { } // Check if we should allow GL_OES_texture_npot - if (helper.HasExtension("GL_ARB_texture_non_power_of_two") || - helper.HasExtension("GL_OES_texture_npot")) { + if (ext.Desire("GL_OES_texture_npot") && + (ext.Have("GL_ARB_texture_non_power_of_two") || + ext.Have("GL_OES_texture_npot"))) { AddExtensionString("GL_OES_texture_npot"); npot_ok = true; } @@ -184,21 +207,21 @@ void FeatureInfo::AddFeatures(const char* desired_features) { bool enable_texture_float_linear = false; bool enable_texture_half_float = false; bool enable_texture_half_float_linear = false; - if (helper.HasExtension("GL_ARB_texture_float")) { + if (ext.HaveAndDesire("GL_ARB_texture_float")) { enable_texture_float = true; enable_texture_float_linear = true; enable_texture_half_float = true; enable_texture_half_float_linear = true; } else { - if (helper.HasExtension("GL_OES_texture_float")) { + if (ext.HaveAndDesire("GL_OES_texture_float")) { enable_texture_float = true; - if (helper.HasExtension("GL_OES_texture_float_linear")) { + if (ext.HaveAndDesire("GL_OES_texture_float_linear")) { enable_texture_float_linear = true; } } - if (helper.HasExtension("GL_OES_texture_half_float")) { + if (ext.HaveAndDesire("GL_OES_texture_half_float")) { enable_texture_half_float = true; - if (helper.HasExtension("GL_OES_texture_half_float_linear")) { + if (ext.HaveAndDesire("GL_OES_texture_half_float_linear")) { enable_texture_half_float_linear = true; } } @@ -221,24 +244,26 @@ void FeatureInfo::AddFeatures(const char* desired_features) { } // Check for multisample support - if (helper.HasExtension("GL_EXT_framebuffer_multisample")) { - feature_flags_.ext_framebuffer_multisample = true; + if (ext.Desire("GL_CHROMIUM_framebuffer_multisample") && + ext.Have("GL_EXT_framebuffer_multisample")) { + feature_flags_.chromium_framebuffer_multisample = true; validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT); validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT); validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT); validators_.render_buffer_parameter.AddValue(GL_MAX_SAMPLES_EXT); - AddExtensionString("GL_EXT_framebuffer_multisample"); - AddExtensionString("GL_EXT_framebuffer_blit"); + AddExtensionString("GL_CHROMIUM_framebuffer_multisample"); } - if (helper.HasExtension("GL_OES_depth24") || - gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) { + if (ext.HaveAndDesire("GL_OES_depth24") || + (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL && + ext.Desire("GL_OES_depth24"))) { AddExtensionString("GL_OES_depth24"); validators_.render_buffer_format.AddValue(GL_DEPTH_COMPONENT24); } - if (helper.HasExtension("GL_OES_standard_derivatives") || - gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL) { + if (ext.HaveAndDesire("GL_OES_standard_derivatives") || + (gfx::GetGLImplementation() == gfx::kGLImplementationDesktopGL && + ext.Desire("GL_OES_standard_derivatives"))) { AddExtensionString("GL_OES_standard_derivatives"); feature_flags_.oes_standard_derivatives = true; } diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index ac6bbed..7a08ccc 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -16,14 +16,14 @@ class FeatureInfo { public: struct FeatureFlags { FeatureFlags() - : ext_framebuffer_multisample(false), + : chromium_framebuffer_multisample(false), oes_standard_derivatives(false), npot_ok(false), enable_texture_float_linear(false), enable_texture_half_float_linear(false) { } - bool ext_framebuffer_multisample; + bool chromium_framebuffer_multisample; bool oes_standard_derivatives; bool npot_ok; bool enable_texture_float_linear; @@ -32,7 +32,7 @@ class FeatureInfo { FeatureInfo(); - // If allowed features = NULL, all features are allowed. Otherwise + // If allowed features = NULL or "*", all features are allowed. Otherwise // only features that match the strings in allowed_features are allowed. bool Initialize(const char* allowed_features); diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc index 67f7cce..710f92b 100644 --- a/gpu/command_buffer/service/feature_info_unittest.cc +++ b/gpu/command_buffer/service/feature_info_unittest.cc @@ -54,7 +54,7 @@ class FeatureInfoTest : public testing::Test { TEST_F(FeatureInfoTest, Basic) { // Test it starts off uninitialized. - EXPECT_FALSE(info_.feature_flags().ext_framebuffer_multisample); + EXPECT_FALSE(info_.feature_flags().chromium_framebuffer_multisample); EXPECT_FALSE(info_.feature_flags().oes_standard_derivatives); EXPECT_FALSE(info_.feature_flags().npot_ok); EXPECT_FALSE(info_.feature_flags().enable_texture_float_linear); @@ -267,9 +267,9 @@ TEST_F(FeatureInfoTest, InitializeOES_texture_half_float_linearGLES2) { TEST_F(FeatureInfoTest, InitializeEXT_framebuffer_multisample) { SetupInitExpectations("GL_EXT_framebuffer_multisample"); info_.Initialize(NULL); - EXPECT_TRUE(info_.feature_flags().ext_framebuffer_multisample); - EXPECT_THAT(info_.extensions(), HasSubstr("GL_EXT_framebuffer_multisample")); - EXPECT_THAT(info_.extensions(), HasSubstr("GL_EXT_framebuffer_blit")); + EXPECT_TRUE(info_.feature_flags().chromium_framebuffer_multisample); + EXPECT_THAT(info_.extensions(), + HasSubstr("GL_CHROMIUM_framebuffer_multisample")); EXPECT_TRUE(info_.validators()->frame_buffer_target.IsValid( GL_READ_FRAMEBUFFER_EXT)); EXPECT_TRUE(info_.validators()->frame_buffer_target.IsValid( diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 6859c85..e3374c0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -370,9 +370,8 @@ bool ContextCreationAttribParser::Parse(const std::vector<int32>& attribs) { // } // anonymous namespace. -GLES2Decoder::GLES2Decoder(ContextGroup* group) - : group_(group), - debug_(false) { +GLES2Decoder::GLES2Decoder() + : debug_(false) { } GLES2Decoder::~GLES2Decoder() { @@ -627,6 +626,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // Overridden from GLES2Decoder. virtual bool Initialize(gfx::GLContext* context, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GLES2Decoder* parent, uint32 parent_client_texture_id); @@ -636,6 +636,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, virtual bool MakeCurrent(); virtual GLES2Util* GetGLES2Util() { return &util_; } virtual gfx::GLContext* GetGLContext() { return context_.get(); } + virtual ContextGroup* GetContextGroup() { return group_.get(); } virtual void SetSwapBuffersCallback(Callback0::Type* callback); virtual bool GetServiceTextureId(uint32 client_texture_id, @@ -1267,6 +1268,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>, // The GL context this decoder renders to on behalf of the client. scoped_ptr<gfx::GLContext> context_; + // The ContextGroup for this decoder uses to track resources. + ContextGroup::Ref group_; + // A parent decoder can access this decoders saved offscreen frame buffer. // The parent pointer is reset if the parent is destroyed. base::WeakPtr<GLES2DecoderImpl> parent_; @@ -1653,7 +1657,8 @@ GLES2Decoder* GLES2Decoder::Create(ContextGroup* group) { } GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) - : GLES2Decoder(group), + : GLES2Decoder(), + group_(ContextGroup::Ref(group ? group : new ContextGroup())), error_bits_(0), util_(0), // TODO(gman): Set to actual num compress texture formats. pack_alignment_(4), @@ -1701,6 +1706,7 @@ GLES2DecoderImpl::GLES2DecoderImpl(ContextGroup* group) bool GLES2DecoderImpl::Initialize(gfx::GLContext* context, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GLES2Decoder* parent, uint32 parent_client_texture_id) { @@ -1722,6 +1728,12 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context, return false; } + if (!group_->Initialize(allowed_extensions)) { + LOG(ERROR) << "GPUProcessor::InitializeCommon failed because group " + << "failed to initialize."; + Destroy(); + } + CHECK_GL_ERROR(); vertex_attrib_manager_.Initialize(group_->max_vertex_attribs()); @@ -1756,7 +1768,7 @@ bool GLES2DecoderImpl::Initialize(gfx::GLContext* context, return false; if (attrib_parser.samples_ > 0 && attrib_parser.sample_buffers_ > 0 && - (feature_info_->feature_flags().ext_framebuffer_multisample || + (feature_info_->feature_flags().chromium_framebuffer_multisample || context_->HasExtension("GL_ANGLE_framebuffer_multisample"))) { // Per ext_framebuffer_multisample spec, need max bound on sample count. GLint max_sample_count; @@ -2059,7 +2071,7 @@ static void RebindCurrentFramebuffer( } void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() { - if (!feature_info_->feature_flags().ext_framebuffer_multisample) { + if (!feature_info_->feature_flags().chromium_framebuffer_multisample) { RebindCurrentFramebuffer( GL_FRAMEBUFFER, bound_draw_framebuffer_.get(), @@ -2094,8 +2106,9 @@ gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() { int width = 0; int height = 0; - GLenum target = feature_info_->feature_flags().ext_framebuffer_multisample ? - GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; + GLenum target = + feature_info_->feature_flags().chromium_framebuffer_multisample ? + GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER; // Assume we have to have COLOR_ATTACHMENT0. Should we check for depth and // stencil. @@ -3378,7 +3391,7 @@ void GLES2DecoderImpl::DoBlitFramebufferEXT( GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - if (!feature_info_->feature_flags().ext_framebuffer_multisample) { + if (!feature_info_->feature_flags().chromium_framebuffer_multisample) { SetGLError(GL_INVALID_OPERATION, "glBlitFramebufferEXT: function not available"); } @@ -3389,7 +3402,7 @@ void GLES2DecoderImpl::DoBlitFramebufferEXT( void GLES2DecoderImpl::DoRenderbufferStorageMultisample( GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { - if (!feature_info_->feature_flags().ext_framebuffer_multisample) { + if (!feature_info_->feature_flags().chromium_framebuffer_multisample) { SetGLError(GL_INVALID_OPERATION, "glRenderbufferStorageMultisampleEXT: function not available"); return; @@ -5596,9 +5609,9 @@ error::Error GLES2DecoderImpl::HandleSwapBuffers( offscreen_saved_color_texture_->Copy( offscreen_saved_color_texture_->size()); - // Ensure the side effects of the copy are visible to the parent context. - // There is no need to do this for ANGLE because it uses a single D3D - // device for all contexts. + // Ensure the side effects of the copy are visible to the parent + // context. There is no need to do this for ANGLE because it uses a + // single D3D device for all contexts. if (!IsAngle()) glFlush(); } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h index f23198e..5c8b735 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -50,9 +50,9 @@ class GLES2Decoder : public CommonDecoder { // Parameters: // context: the GL context to render to. // size: the size if the GL context is offscreen. - // allowed_features: A string in the same format as + // allowed_extensions: A string in the same format as // glGetString(GL_EXTENSIONS) that lists the extensions this context - // should allow. Passing NULL means allow all extensions. + // should allow. Passing NULL or "*" means allow all extensions. // parent: the GLES2 decoder that can access this decoder's front buffer // through a texture ID in its namespace. // parent_client_texture_id: the texture ID of the front buffer in the @@ -61,6 +61,7 @@ class GLES2Decoder : public CommonDecoder { // true if successful. virtual bool Initialize(gfx::GLContext* context, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GLES2Decoder* parent, uint32 parent_client_texture_id) = 0; @@ -85,6 +86,9 @@ class GLES2Decoder : public CommonDecoder { // Gets the associated GLContext. virtual gfx::GLContext* GetGLContext() = 0; + // Gets the associated ContextGroup + virtual ContextGroup* GetContextGroup() = 0; + // Sets a callback which is called when a SwapBuffers command is processed. virtual void SetSwapBuffersCallback(Callback0::Type* callback) = 0; @@ -96,9 +100,7 @@ class GLES2Decoder : public CommonDecoder { } protected: - explicit GLES2Decoder(ContextGroup* group); - - ContextGroup* group_; + GLES2Decoder(); private: bool debug_; diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h index 4034f54..bee0202 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_mock.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_mock.h @@ -22,16 +22,17 @@ namespace gles2 { class ContextGroup; class MockGLES2Decoder : public GLES2Decoder { public: - explicit MockGLES2Decoder(ContextGroup* group) - : GLES2Decoder(group) { + MockGLES2Decoder() + : GLES2Decoder() { ON_CALL(*this, GetCommandName(testing::_)) .WillByDefault(testing::Return("")); ON_CALL(*this, MakeCurrent()) .WillByDefault(testing::Return(true)); } - MOCK_METHOD5(Initialize, bool(gfx::GLContext* context, + MOCK_METHOD6(Initialize, bool(gfx::GLContext* context, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GLES2Decoder* parent, uint32 parent_texture_id)); @@ -42,6 +43,7 @@ class MockGLES2Decoder : public GLES2Decoder { MOCK_METHOD1(GetServiceIdForTesting, uint32(uint32 client_id)); MOCK_METHOD0(GetGLES2Util, GLES2Util*()); MOCK_METHOD0(GetGLContext, gfx::GLContext*()); + MOCK_METHOD0(GetContextGroup, ContextGroup*()); MOCK_METHOD1(SetSwapBuffersCallback, void(Callback0::Type*)); MOCK_METHOD3(DoCommand, error::Error(unsigned int command, unsigned int arg_count, diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc index c923676..79af216 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc @@ -39,12 +39,13 @@ void GLES2DecoderTestBase::SetUp() { void GLES2DecoderTestBase::InitDecoder(const char* extensions) { gl_.reset(new StrictMock<MockGLInterface>()); ::gfx::GLInterface::SetGLInterface(gl_.get()); + group_ = ContextGroup::Ref(new ContextGroup()); InSequence sequence; TestHelper::SetupContextGroupInitExpectations(gl_.get(), extensions); - EXPECT_TRUE(group_.Initialize(extensions)); + EXPECT_TRUE(group_->Initialize(extensions)); EXPECT_CALL(*gl_, EnableVertexAttribArray(0)) .Times(1) @@ -100,8 +101,9 @@ void GLES2DecoderTestBase::InitDecoder(const char* extensions) { context_ = new gfx::StubGLContext; - decoder_.reset(GLES2Decoder::Create(&group_)); - decoder_->Initialize(context_, gfx::Size(), std::vector<int32>(), NULL, 0); + decoder_.reset(GLES2Decoder::Create(group_.get())); + decoder_->Initialize( + context_, gfx::Size(), NULL, std::vector<int32>(), NULL, 0); decoder_->set_engine(engine_.get()); EXPECT_CALL(*gl_, GenBuffersARB(_, _)) @@ -148,7 +150,8 @@ void GLES2DecoderTestBase::TearDown() { .RetiresOnSaturation(); decoder_->Destroy(); decoder_.reset(); - group_.Destroy(false); + group_->SetLostContext(); + group_ = NULL; engine_.reset(); ::gfx::GLInterface::SetGLInterface(NULL); gl_.reset(); diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h index a783136..d5981c7 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h @@ -131,32 +131,32 @@ class GLES2DecoderTestBase : public testing::Test { } IdAllocator* GetIdAllocator(GLuint namespace_id) { - return group_.GetIdAllocator(namespace_id); + return group_->GetIdAllocator(namespace_id); } BufferManager::BufferInfo* GetBufferInfo(GLuint service_id) { - return group_.buffer_manager()->GetBufferInfo(service_id); + return group_->buffer_manager()->GetBufferInfo(service_id); } FramebufferManager::FramebufferInfo* GetFramebufferInfo(GLuint service_id) { - return group_.framebuffer_manager()->GetFramebufferInfo(service_id); + return group_->framebuffer_manager()->GetFramebufferInfo(service_id); } RenderbufferManager::RenderbufferInfo* GetRenderbufferInfo( GLuint service_id) { - return group_.renderbuffer_manager()->GetRenderbufferInfo(service_id); + return group_->renderbuffer_manager()->GetRenderbufferInfo(service_id); } TextureManager::TextureInfo* GetTextureInfo(GLuint service_id) { - return group_.texture_manager()->GetTextureInfo(service_id); + return group_->texture_manager()->GetTextureInfo(service_id); } ShaderManager::ShaderInfo* GetShaderInfo(GLuint service_id) { - return group_.shader_manager()->GetShaderInfo(service_id); + return group_->shader_manager()->GetShaderInfo(service_id); } ProgramManager::ProgramInfo* GetProgramInfo(GLuint service_id) { - return group_.program_manager()->GetProgramInfo(service_id); + return group_->program_manager()->GetProgramInfo(service_id); } void DoCreateShader(GLenum shader_type, GLuint client_id, GLuint service_id); @@ -166,7 +166,7 @@ class GLES2DecoderTestBase : public testing::Test { void InitDecoder(const char* extensions); const ContextGroup& group() const { - return group_; + return *group_.get(); } struct AttribInfo { @@ -294,7 +294,7 @@ class GLES2DecoderTestBase : public testing::Test { }; scoped_ptr< ::testing::StrictMock<MockCommandBufferEngine> > engine_; - ContextGroup group_; + ContextGroup::Ref group_; }; class GLES2DecoderWithShaderTestBase : public GLES2DecoderTestBase { diff --git a/gpu/command_buffer/service/gpu_processor.cc b/gpu/command_buffer/service/gpu_processor.cc index aab77db..d32cb62 100644 --- a/gpu/command_buffer/service/gpu_processor.cc +++ b/gpu/command_buffer/service/gpu_processor.cc @@ -12,12 +12,13 @@ using ::base::SharedMemory; namespace gpu { -GPUProcessor::GPUProcessor(CommandBuffer* command_buffer) +GPUProcessor::GPUProcessor(CommandBuffer* command_buffer, + gles2::ContextGroup* group) : command_buffer_(command_buffer), commands_per_update_(100), method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { DCHECK(command_buffer); - decoder_.reset(gles2::GLES2Decoder::Create(&group_)); + decoder_.reset(gles2::GLES2Decoder::Create(group)); decoder_->set_engine(this); } @@ -39,6 +40,7 @@ GPUProcessor::~GPUProcessor() { bool GPUProcessor::InitializeCommon(gfx::GLContext* context, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, gles2::GLES2Decoder* parent_decoder, uint32 parent_texture_id) { @@ -58,16 +60,10 @@ bool GPUProcessor::InitializeCommon(gfx::GLContext* context, decoder_.get())); } - if (!group_.Initialize(NULL)) { - LOG(ERROR) << "GPUProcessor::InitializeCommon failed because group " - << "failed to initialize."; - Destroy(); - return false; - } - // Initialize the decoder with either the view or pbuffer GLContext. if (!decoder_->Initialize(context, size, + allowed_extensions, attribs, parent_decoder, parent_texture_id)) { @@ -88,8 +84,6 @@ void GPUProcessor::DestroyCommon() { decoder_.reset(); } - group_.Destroy(have_context); - parser_.reset(); } diff --git a/gpu/command_buffer/service/gpu_processor.h b/gpu/command_buffer/service/gpu_processor.h index 417f4e0..79d9e73 100644 --- a/gpu/command_buffer/service/gpu_processor.h +++ b/gpu/command_buffer/service/gpu_processor.h @@ -18,7 +18,6 @@ #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/context_group.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #if defined(OS_MACOSX) @@ -30,12 +29,16 @@ class GLContext; } 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. class GPUProcessor : public CommandBufferEngine { public: - explicit GPUProcessor(CommandBuffer* command_buffer); + // If a group is not passed in one will be created. + GPUProcessor(CommandBuffer* command_buffer, gles2::ContextGroup* group); // This constructor is for unit tests. GPUProcessor(CommandBuffer* command_buffer, @@ -48,17 +51,11 @@ class GPUProcessor : public CommandBufferEngine { // Perform platform specific and common initialization. bool Initialize(gfx::PluginWindowHandle hwnd, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GPUProcessor* parent, uint32 parent_texture_id); - // Perform common initialization. Takes ownership of GLContext. - bool InitializeCommon(gfx::GLContext* context, - const gfx::Size& size, - const std::vector<int32>& attribs, - gles2::GLES2Decoder* parent_decoder, - uint32 parent_texture_id); - void Destroy(); void DestroyCommon(); @@ -96,6 +93,16 @@ class GPUProcessor : public CommandBufferEngine { // Get the GLES2Decoder associated with this processor. gles2::GLES2Decoder* decoder() const { return decoder_.get(); } + protected: + // Perform common initialization. Takes ownership of GLContext. + bool InitializeCommon(gfx::GLContext* context, + const gfx::Size& size, + const char* allowed_extensions, + const std::vector<int32>& attribs, + gles2::GLES2Decoder* parent_decoder, + uint32 parent_texture_id); + + private: // Called via a callback just before we are supposed to call the // user's swap buffers callback. @@ -108,9 +115,6 @@ class GPUProcessor : public CommandBufferEngine { int commands_per_update_; - // TODO(gman): Group needs to be passed in so it can be shared by - // multiple GPUProcessors. - gles2::ContextGroup group_; scoped_ptr<gles2::GLES2Decoder> decoder_; scoped_ptr<CommandParser> parser_; diff --git a/gpu/command_buffer/service/gpu_processor_linux.cc b/gpu/command_buffer/service/gpu_processor_linux.cc index 9938558..cca8663 100644 --- a/gpu/command_buffer/service/gpu_processor_linux.cc +++ b/gpu/command_buffer/service/gpu_processor_linux.cc @@ -11,6 +11,7 @@ namespace gpu { bool GPUProcessor::Initialize(gfx::PluginWindowHandle window, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GPUProcessor* parent, uint32 parent_texture_id) { @@ -44,6 +45,7 @@ bool GPUProcessor::Initialize(gfx::PluginWindowHandle window, return InitializeCommon(context.release(), size, + allowed_extensions, attribs, parent_decoder, parent_texture_id); diff --git a/gpu/command_buffer/service/gpu_processor_mac.cc b/gpu/command_buffer/service/gpu_processor_mac.cc index 97b38a4..17dee69 100644 --- a/gpu/command_buffer/service/gpu_processor_mac.cc +++ b/gpu/command_buffer/service/gpu_processor_mac.cc @@ -11,6 +11,7 @@ namespace gpu { bool GPUProcessor::Initialize(gfx::PluginWindowHandle window, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GPUProcessor* parent, uint32 parent_texture_id) { @@ -52,6 +53,7 @@ bool GPUProcessor::Initialize(gfx::PluginWindowHandle window, return InitializeCommon(context.release(), size, + allowed_extensions, attribs, parent_decoder, parent_texture_id); diff --git a/gpu/command_buffer/service/gpu_processor_unittest.cc b/gpu/command_buffer/service/gpu_processor_unittest.cc index 69adf03..ffba24e 100644 --- a/gpu/command_buffer/service/gpu_processor_unittest.cc +++ b/gpu/command_buffer/service/gpu_processor_unittest.cc @@ -5,7 +5,6 @@ #include "base/mac/scoped_nsautorelease_pool.h" #include "base/message_loop.h" #include "gpu/command_buffer/common/command_buffer_mock.h" -#include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gpu_processor.h" #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h" @@ -48,7 +47,7 @@ class GPUProcessorTest : public testing::Test { async_api_.reset(new StrictMock<AsyncAPIMock>); - decoder_ = new gles2::MockGLES2Decoder(&group_); + decoder_ = new gles2::MockGLES2Decoder(); parser_ = new CommandParser(buffer_, kRingBufferEntries, @@ -83,7 +82,6 @@ class GPUProcessorTest : public testing::Test { scoped_ptr<base::SharedMemory> shared_memory_; Buffer shared_memory_buffer_; int32* buffer_; - gles2::ContextGroup group_; gles2::MockGLES2Decoder* decoder_; CommandParser* parser_; scoped_ptr<AsyncAPIMock> async_api_; diff --git a/gpu/command_buffer/service/gpu_processor_win.cc b/gpu/command_buffer/service/gpu_processor_win.cc index a4fd90b..0ec6b1c 100644 --- a/gpu/command_buffer/service/gpu_processor_win.cc +++ b/gpu/command_buffer/service/gpu_processor_win.cc @@ -13,6 +13,7 @@ namespace gpu { bool GPUProcessor::Initialize(gfx::PluginWindowHandle window, const gfx::Size& size, + const char* allowed_extensions, const std::vector<int32>& attribs, GPUProcessor* parent, uint32 parent_texture_id) { @@ -43,6 +44,7 @@ bool GPUProcessor::Initialize(gfx::PluginWindowHandle window, return InitializeCommon(context.release(), size, + allowed_extensions, attribs, parent_decoder, parent_texture_id); diff --git a/gpu/demos/framework/window.cc b/gpu/demos/framework/window.cc index 881452a..825025ef 100644 --- a/gpu/demos/framework/window.cc +++ b/gpu/demos/framework/window.cc @@ -60,8 +60,8 @@ bool Window::CreateRenderContext(gfx::PluginWindowHandle hwnd) { } GPUProcessor* gpu_processor( - new GPUProcessor(command_buffer.get())); - if (!gpu_processor->Initialize(hwnd, gfx::Size(), std::vector<int32>(), + new GPUProcessor(command_buffer.get(), NULL)); + if (!gpu_processor->Initialize(hwnd, gfx::Size(), NULL, std::vector<int32>(), NULL, 0)) { return false; } |