Update the native_viewport interface to allow specification of the surface configuration, currently only needed for and used by EGL on Android. This also fixes an issue where eglChooseConfig was only being called in InitializeOneOff, which is only called once per process. This CL makes choosing the config happen once per GLSurface instead, which will ultimately permit apps to create multiple native_viewports with different surface configurations on the same display. The eglDisplay object is still a global, though. R=abarth@chromium.org, viettrungluu@chromium.org, jamesr@chromium.org Review URL: https://codereview.chromium.org/1168993002.
diff --git a/apps/moterm/gl_helper_test_app.cc b/apps/moterm/gl_helper_test_app.cc index f5cff3b..e2c88e3 100644 --- a/apps/moterm/gl_helper_test_app.cc +++ b/apps/moterm/gl_helper_test_app.cc
@@ -218,7 +218,7 @@ viewport_size_.width = 800; viewport_size_.height = 600; native_viewport_->Create( - viewport_size_.Clone(), + viewport_size_.Clone(), mojo::SurfaceConfiguration::New(), base::Bind(&GlHelperExampleApp::OnViewportMetricsReceived, base::Unretained(this))); native_viewport_->Show();
diff --git a/examples/spinning_cube/spinning_cube_app.cc b/examples/spinning_cube/spinning_cube_app.cc index 42e64b0..9ff7b4c 100644 --- a/examples/spinning_cube/spinning_cube_app.cc +++ b/examples/spinning_cube/spinning_cube_app.cc
@@ -41,8 +41,13 @@ mojo::SizePtr size(mojo::Size::New()); size->width = 800; size->height = 600; + + auto requested_configuration = mojo::SurfaceConfiguration::New(); + requested_configuration->depth_bits = 16; + viewport_->Create( size.Clone(), + requested_configuration.Pass(), base::Bind(&SpinningCubeApp::OnMetricsChanged, base::Unretained(this))); viewport_->Show(); mojo::ContextProviderPtr onscreen_context_provider;
diff --git a/examples/surfaces_app/surfaces_app.cc b/examples/surfaces_app/surfaces_app.cc index e254b59..2e07629 100644 --- a/examples/surfaces_app/surfaces_app.cc +++ b/examples/surfaces_app/surfaces_app.cc
@@ -39,7 +39,8 @@ // Connect to the native viewport service and create a viewport. app_impl_->ConnectToService("mojo:native_viewport_service", &viewport_); - viewport_->Create(Size::From(size_), [](ViewportMetricsPtr metrics) {}); + viewport_->Create(Size::From(size_), SurfaceConfiguration::New(), + [](ViewportMetricsPtr metrics) {}); viewport_->Show(); // Grab a ContextProvider associated with the viewport.
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc index e7a3a6c..977822e 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_egl.cc
@@ -97,7 +97,8 @@ void Init() override { gfx::GLShareGroup* share_group = NULL; - surface_ = new gfx::PbufferGLSurfaceEGL(gfx::Size(1, 1)); + surface_ = new gfx::PbufferGLSurfaceEGL(gfx::Size(1, 1), + gfx::SurfaceConfiguration()); surface_->Initialize(); context_ = gfx::GLContext::CreateGLContext( share_group, surface_.get(), gfx::PreferDiscreteGpu);
diff --git a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc index 47cdf9e..45e5e5c 100644 --- a/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc +++ b/gpu/command_buffer/service/async_pixel_transfer_manager_share_group.cc
@@ -92,7 +92,8 @@ return; } - surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); + surface_ = gfx::GLSurface::CreateOffscreenGLSurface( + gfx::Size(1, 1), gfx::SurfaceConfiguration()); if (!surface_.get()) { LOG(ERROR) << "Unable to create GLSurface"; caller_wait->Signal();
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc index 65986f8..2036ed0 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.cc +++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -240,6 +240,30 @@ } // anonyous namespace + +InProcessCommandBuffer:: + InitializeOnGpuThreadParams::InitializeOnGpuThreadParams( + bool is_offscreen, + gfx::AcceleratedWidget window, + const gfx::Size& size, + const std::vector<int32>& attribs, + gfx::GpuPreference gpu_preference, + gpu::Capabilities* capabilities, + InProcessCommandBuffer* share_group, + ImageFactory* image_factory, + const gfx::SurfaceConfiguration& requested_configuration) + : is_offscreen(is_offscreen), + window(window), + size(size), + attribs(attribs), + gpu_preference(gpu_preference), + capabilities(capabilities), + context_group(share_group), + image_factory(image_factory), + requested_configuration(requested_configuration) { +} + + InProcessCommandBuffer::Service::Service() {} InProcessCommandBuffer::Service::~Service() {} @@ -343,7 +367,8 @@ const base::Closure& context_lost_callback, InProcessCommandBuffer* share_group, GpuMemoryBufferManager* gpu_memory_buffer_manager, - ImageFactory* image_factory) { + ImageFactory* image_factory, + const gfx::SurfaceConfiguration& requested_configuration) { DCHECK(!share_group || service_.get() == share_group->service_.get()); context_lost_callback_ = WrapCallback(context_lost_callback); @@ -362,7 +387,8 @@ gpu_preference, &capabilities, share_group, - image_factory); + image_factory, + requested_configuration); base::Callback<bool(void)> init_task = base::Bind(&InProcessCommandBuffer::InitializeOnGpuThread, @@ -439,9 +465,11 @@ if (!surface_.get()) { if (params.is_offscreen) - surface_ = gfx::GLSurface::CreateOffscreenGLSurface(params.size); + surface_ = gfx::GLSurface::CreateOffscreenGLSurface( + params.size, params.requested_configuration); else - surface_ = gfx::GLSurface::CreateViewGLSurface(params.window); + surface_ = gfx::GLSurface::CreateViewGLSurface( + params.window, params.requested_configuration); } if (!surface_.get()) {
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index b3f6eb8..1c51832 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -84,7 +84,8 @@ const base::Closure& context_lost_callback, InProcessCommandBuffer* share_group, GpuMemoryBufferManager* gpu_memory_buffer_manager, - ImageFactory* image_factory); + ImageFactory* image_factory, + const gfx::SurfaceConfiguration& requested_configuration); void Destroy(); // CommandBuffer implementation: @@ -168,23 +169,18 @@ gpu::Capabilities* capabilities; // Ouptut. InProcessCommandBuffer* context_group; ImageFactory* image_factory; + gfx::SurfaceConfiguration requested_configuration; - InitializeOnGpuThreadParams(bool is_offscreen, - gfx::AcceleratedWidget window, - const gfx::Size& size, - const std::vector<int32>& attribs, - gfx::GpuPreference gpu_preference, - gpu::Capabilities* capabilities, - InProcessCommandBuffer* share_group, - ImageFactory* image_factory) - : is_offscreen(is_offscreen), - window(window), - size(size), - attribs(attribs), - gpu_preference(gpu_preference), - capabilities(capabilities), - context_group(share_group), - image_factory(image_factory) {} + InitializeOnGpuThreadParams( + bool is_offscreen, + gfx::AcceleratedWidget window, + const gfx::Size& size, + const std::vector<int32>& attribs, + gfx::GpuPreference gpu_preference, + gpu::Capabilities* capabilities, + InProcessCommandBuffer* share_group, + ImageFactory* image_factory, + const gfx::SurfaceConfiguration& requested_configuration); }; bool InitializeOnGpuThread(const InitializeOnGpuThreadParams& params);
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index 521f2cd..0851bca 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc
@@ -22,7 +22,8 @@ scoped_refptr<gfx::GLSurface> InitializeGLSurface() { scoped_refptr<gfx::GLSurface> surface( - gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size())); + gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(), + gfx::SurfaceConfiguration())); if (!surface.get()) { LOG(ERROR) << "gfx::GLContext::CreateOffscreenGLSurface failed"; return NULL;
diff --git a/mojo/converters/native_viewport/BUILD.gn b/mojo/converters/native_viewport/BUILD.gn new file mode 100644 index 0000000..c70f119 --- /dev/null +++ b/mojo/converters/native_viewport/BUILD.gn
@@ -0,0 +1,18 @@ +# Copyright 2015 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. + +component("native_viewport") { + sources = [ + "surface_configuration_type_converters.cc", + "surface_configuration_type_converters.h", + ] + + deps = [ + "//base", + "//ui/gl", + "//mojo/environment:chromium", + "//mojo/public/c/system", + "//mojo/services/native_viewport/public/interfaces", + ] +}
diff --git a/mojo/converters/native_viewport/surface_configuration_type_converters.cc b/mojo/converters/native_viewport/surface_configuration_type_converters.cc new file mode 100644 index 0000000..2719f05 --- /dev/null +++ b/mojo/converters/native_viewport/surface_configuration_type_converters.cc
@@ -0,0 +1,23 @@ +// Copyright 2015 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 "mojo/converters/native_viewport/surface_configuration_type_converters.h" + +namespace mojo { + +// static +gfx::SurfaceConfiguration +TypeConverter<gfx::SurfaceConfiguration, SurfaceConfigurationPtr>::Convert( + const SurfaceConfigurationPtr& input) { + auto output = gfx::SurfaceConfiguration(); + output.red_bits = input->red_bits; + output.green_bits = input->green_bits; + output.blue_bits = input->blue_bits; + output.alpha_bits = input->alpha_bits; + output.depth_bits = input->depth_bits; + output.stencil_bits = input->stencil_bits; + return output; +} + +} // namespace mojo \ No newline at end of file
diff --git a/mojo/converters/native_viewport/surface_configuration_type_converters.h b/mojo/converters/native_viewport/surface_configuration_type_converters.h new file mode 100644 index 0000000..4389adf --- /dev/null +++ b/mojo/converters/native_viewport/surface_configuration_type_converters.h
@@ -0,0 +1,23 @@ +// Copyright 2014 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 MOJO_CONVERTERS_NATIVE_VIEWPORT_SURFACE_CONFIGURATION_TYPE_CONVERTERS_H_ +#define MOJO_CONVERTERS_NATIVE_VIEWPORT_SURFACE_CONFIGURATION_TYPE_CONVERTERS_H_ + +#include "base/memory/scoped_ptr.h" +#include "mojo/services/native_viewport/public/interfaces/native_viewport.mojom.h" +#include "ui/gl/gl_surface.h" + +namespace mojo { + +// Types from native_viewport.mojom +template <> +struct TypeConverter<gfx::SurfaceConfiguration, SurfaceConfigurationPtr> { + static gfx::SurfaceConfiguration Convert( + const SurfaceConfigurationPtr& input); +}; + +} // namespace mojo + +#endif // MOJO_CONVERTERS_NATIVE_VIEWPORT_SURFACE_CONFIGURATION_TYPE_CONVERTERS_H_
diff --git a/mojo/services/native_viewport/public/interfaces/native_viewport.mojom b/mojo/services/native_viewport/public/interfaces/native_viewport.mojom index 21cace6..641d1c0 100644 --- a/mojo/services/native_viewport/public/interfaces/native_viewport.mojom +++ b/mojo/services/native_viewport/public/interfaces/native_viewport.mojom
@@ -13,10 +13,19 @@ float device_pixel_ratio = 1.0; }; +struct SurfaceConfiguration { + uint8 red_bits = 8; + uint8 green_bits = 8; + uint8 blue_bits = 8; + uint8 alpha_bits = 8; + uint8 depth_bits; + uint8 stencil_bits; +}; + interface NativeViewport { // TODO(sky): having a create function is awkward. Should there be a factory // to create the NativeViewport that takes the size? - Create(Size size) => (ViewportMetrics metrics); + Create(Size size, SurfaceConfiguration? requested_configuration) => (ViewportMetrics metrics); Show(); Hide();
diff --git a/services/gles2/command_buffer_driver.cc b/services/gles2/command_buffer_driver.cc index 50d1b97..6ba980f 100644 --- a/services/gles2/command_buffer_driver.cc +++ b/services/gles2/command_buffer_driver.cc
@@ -53,23 +53,27 @@ CommandBufferDriver::CommandBufferDriver( gfx::GLShareGroup* share_group, gpu::gles2::MailboxManager* mailbox_manager, - gpu::SyncPointManager* sync_point_manager) + gpu::SyncPointManager* sync_point_manager, + const gfx::SurfaceConfiguration& requested_configuration) : CommandBufferDriver(gfx::kNullAcceleratedWidget, share_group, mailbox_manager, - sync_point_manager) { + sync_point_manager, + requested_configuration) { } CommandBufferDriver::CommandBufferDriver( gfx::AcceleratedWidget widget, gfx::GLShareGroup* share_group, gpu::gles2::MailboxManager* mailbox_manager, - gpu::SyncPointManager* sync_point_manager) + gpu::SyncPointManager* sync_point_manager, + const gfx::SurfaceConfiguration& requested_configuration) : client_(nullptr), widget_(widget), share_group_(share_group), mailbox_manager_(mailbox_manager), sync_point_manager_(sync_point_manager), + requested_configuration_(requested_configuration), weak_factory_(this) { } @@ -96,9 +100,11 @@ bool CommandBufferDriver::DoInitialize( mojo::ScopedSharedBufferHandle shared_state) { if (widget_ == gfx::kNullAcceleratedWidget) - surface_ = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); + surface_ = gfx::GLSurface::CreateOffscreenGLSurface( + gfx::Size(1, 1), requested_configuration_); else { - surface_ = gfx::GLSurface::CreateViewGLSurface(widget_); + surface_ = + gfx::GLSurface::CreateViewGLSurface(widget_, requested_configuration_); if (auto vsync_provider = surface_->GetVSyncProvider()) { vsync_provider->GetVSyncParameters( base::Bind(&CommandBufferDriver::OnUpdateVSyncParameters,
diff --git a/services/gles2/command_buffer_driver.h b/services/gles2/command_buffer_driver.h index 6d1fd34..c3d6501 100644 --- a/services/gles2/command_buffer_driver.h +++ b/services/gles2/command_buffer_driver.h
@@ -13,6 +13,7 @@ #include "mojo/services/gpu/public/interfaces/command_buffer.mojom.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/size.h" +#include "ui/gl/gl_surface.h" namespace gpu { class CommandBufferService; @@ -45,12 +46,14 @@ // Offscreen. CommandBufferDriver(gfx::GLShareGroup* share_group, gpu::gles2::MailboxManager* mailbox_manager, - gpu::SyncPointManager* sync_point_manager); + gpu::SyncPointManager* sync_point_manager, + const gfx::SurfaceConfiguration& requested_configuration); // Onscreen. CommandBufferDriver(gfx::AcceleratedWidget widget, gfx::GLShareGroup* share_group, gpu::gles2::MailboxManager* mailbox_manager, - gpu::SyncPointManager* sync_point_manager); + gpu::SyncPointManager* sync_point_manager, + const gfx::SurfaceConfiguration& requested_configuration); ~CommandBufferDriver(); void set_client(scoped_ptr<Client> client) { client_ = client.Pass(); } @@ -89,6 +92,7 @@ scoped_refptr<gfx::GLShareGroup> share_group_; scoped_refptr<gpu::gles2::MailboxManager> mailbox_manager_; scoped_refptr<gpu::SyncPointManager> sync_point_manager_; + gfx::SurfaceConfiguration requested_configuration_; scoped_refptr<base::SingleThreadTaskRunner> context_lost_task_runner_; base::Callback<void(int32_t)> context_lost_callback_;
diff --git a/services/gles2/gpu_impl.cc b/services/gles2/gpu_impl.cc index 896bb18..9bdf8de 100644 --- a/services/gles2/gpu_impl.cc +++ b/services/gles2/gpu_impl.cc
@@ -30,7 +30,8 @@ state_->sync_point_manager(), make_scoped_ptr(new CommandBufferDriver( state_->share_group(), state_->mailbox_manager(), - state_->sync_point_manager()))); + state_->sync_point_manager(), + gfx::SurfaceConfiguration()))); } } // namespace gles2
diff --git a/services/native_viewport/BUILD.gn b/services/native_viewport/BUILD.gn index 5338c4c..0a73c82 100644 --- a/services/native_viewport/BUILD.gn +++ b/services/native_viewport/BUILD.gn
@@ -83,6 +83,7 @@ "//mojo/common", "//mojo/converters/geometry", "//mojo/converters/input_events", + "//mojo/converters/native_viewport", "//mojo/environment:chromium", "//services/gles2", "//mojo/services/geometry/public/interfaces",
diff --git a/services/native_viewport/native_viewport_impl.cc b/services/native_viewport/native_viewport_impl.cc index f39f53b..7fd4274 100644 --- a/services/native_viewport/native_viewport_impl.cc +++ b/services/native_viewport/native_viewport_impl.cc
@@ -10,10 +10,12 @@ #include "base/message_loop/message_loop.h" #include "base/time/time.h" #include "mojo/converters/geometry/geometry_type_converters.h" +#include "mojo/converters/native_viewport/surface_configuration_type_converters.h" #include "mojo/public/cpp/application/interface_factory.h" #include "services/gles2/gpu_state.h" #include "services/native_viewport/platform_viewport_headless.h" #include "ui/events/event.h" +#include "ui/gl/gl_surface.h" namespace native_viewport { @@ -36,10 +38,17 @@ platform_viewport_.reset(); } -void NativeViewportImpl::Create(mojo::SizePtr size, - const CreateCallback& callback) { +void NativeViewportImpl::Create( + mojo::SizePtr size, + mojo::SurfaceConfigurationPtr requested_configuration, + const CreateCallback& callback) { + if (requested_configuration == nullptr) + requested_configuration = mojo::SurfaceConfiguration::New(); + create_callback_ = callback; metrics_->size = size.Clone(); + context_provider_.set_surface_configuration( + requested_configuration.To<gfx::SurfaceConfiguration>()); if (is_headless_) platform_viewport_ = PlatformViewportHeadless::Create(this); else
diff --git a/services/native_viewport/native_viewport_impl.h b/services/native_viewport/native_viewport_impl.h index 4ac9bbd..4c7f355 100644 --- a/services/native_viewport/native_viewport_impl.h +++ b/services/native_viewport/native_viewport_impl.h
@@ -40,7 +40,9 @@ ~NativeViewportImpl() override; // NativeViewport implementation. - void Create(mojo::SizePtr size, const CreateCallback& callback) override; + void Create(mojo::SizePtr size, + mojo::SurfaceConfigurationPtr requested_configuration, + const CreateCallback& callback) override; void RequestMetrics(const RequestMetricsCallback& callback) override; void Show() override; void Hide() override;
diff --git a/services/native_viewport/onscreen_context_provider.cc b/services/native_viewport/onscreen_context_provider.cc index 90a98dc..fcdf543 100644 --- a/services/native_viewport/onscreen_context_provider.cc +++ b/services/native_viewport/onscreen_context_provider.cc
@@ -11,7 +11,8 @@ OnscreenContextProvider::OnscreenContextProvider( const scoped_refptr<gles2::GpuState>& state) - : command_buffer_impl_(nullptr), + : requested_configuration_(gfx::SurfaceConfiguration()), + command_buffer_impl_(nullptr), state_(state), widget_(gfx::kNullAcceleratedWidget), binding_(this) { @@ -51,6 +52,7 @@ DCHECK(!command_buffer_impl_); pending_create_callback_.Run(nullptr); } + pending_listener_ = viewport_parameter_listener.Pass(); pending_create_callback_ = callback; @@ -70,7 +72,7 @@ state_->sync_point_manager(), make_scoped_ptr(new gles2::CommandBufferDriver( widget_, state_->share_group(), state_->mailbox_manager(), - state_->sync_point_manager()))); + state_->sync_point_manager(), requested_configuration_))); command_buffer_impl_->set_observer(this); pending_create_callback_.Run(cb.Pass()); pending_create_callback_.reset();
diff --git a/services/native_viewport/onscreen_context_provider.h b/services/native_viewport/onscreen_context_provider.h index 46ab1b1..c818913 100644 --- a/services/native_viewport/onscreen_context_provider.h +++ b/services/native_viewport/onscreen_context_provider.h
@@ -10,6 +10,7 @@ #include "mojo/services/gpu/public/interfaces/viewport_parameter_listener.mojom.h" #include "services/gles2/command_buffer_impl.h" #include "ui/gfx/native_widget_types.h" +#include "ui/gl/gl_surface.h" namespace gles2 { class GpuState; @@ -26,7 +27,10 @@ void Bind(mojo::InterfaceRequest<mojo::ContextProvider> request); void SetAcceleratedWidget(gfx::AcceleratedWidget widget); - + void set_surface_configuration( + const gfx::SurfaceConfiguration requested_configuration) { + requested_configuration_ = requested_configuration; + }; private: // mojo::ContextProvider implementation: void Create(mojo::ViewportParameterListenerPtr viewport_parameter_listener, @@ -37,6 +41,7 @@ void CreateAndReturnCommandBuffer(); + gfx::SurfaceConfiguration requested_configuration_; gles2::CommandBufferImpl* command_buffer_impl_; scoped_refptr<gles2::GpuState> state_; gfx::AcceleratedWidget widget_;
diff --git a/services/view_manager/display_manager.cc b/services/view_manager/display_manager.cc index 7536b70..0ecd067 100644 --- a/services/view_manager/display_manager.cc +++ b/services/view_manager/display_manager.cc
@@ -93,6 +93,7 @@ &native_viewport_); native_viewport_.set_error_handler(this); native_viewport_->Create(metrics_.size->Clone(), + mojo::SurfaceConfiguration::New(), base::Bind(&DefaultDisplayManager::OnMetricsChanged, weak_factory_.GetWeakPtr())); native_viewport_->Show();
diff --git a/sky/shell/gpu/rasterizer.cc b/sky/shell/gpu/rasterizer.cc index 52a5525..cb56a05 100644 --- a/sky/shell/gpu/rasterizer.cc +++ b/sky/shell/gpu/rasterizer.cc
@@ -37,7 +37,8 @@ } void Rasterizer::OnAcceleratedWidgetAvailable(gfx::AcceleratedWidget widget) { - surface_ = gfx::GLSurface::CreateViewGLSurface(widget); + surface_ = gfx::GLSurface::CreateViewGLSurface(widget, + gfx::SurfaceConfiguration()); CHECK(surface_) << "GLSurface required."; }
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc index a827503..007bcaf 100644 --- a/ui/gl/gl_surface.cc +++ b/ui/gl/gl_surface.cc
@@ -161,7 +161,9 @@ CHECK(InitializeDynamicGLBindings(kGLImplementationMockGL, context)); } -GLSurface::GLSurface() {} +GLSurface::GLSurface(const SurfaceConfiguration requested_configuration) + : surface_configuration_(requested_configuration) { +} bool GLSurface::Initialize() { return true; @@ -294,7 +296,9 @@ void GLSurface::OnSetSwapInterval(int interval) { } -GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) : surface_(surface) {} +GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) + : GLSurface(surface->get_surface_configuration()), surface_(surface) { +} bool GLSurfaceAdapter::Initialize() { return surface_->Initialize();
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h index da70422..73c085d 100644 --- a/ui/gl/gl_surface.h +++ b/ui/gl/gl_surface.h
@@ -24,11 +24,20 @@ class GLImage; class VSyncProvider; +struct SurfaceConfiguration { + uint8_t red_bits = 8; + uint8_t green_bits = 8; + uint8_t blue_bits = 8; + uint8_t alpha_bits = 8; + uint8_t depth_bits = 0; + uint8_t stencil_bits = 0; +}; + // Encapsulates a surface that can be rendered to with GL, hiding platform // specific management. class GL_EXPORT GLSurface : public base::RefCounted<GLSurface> { public: - GLSurface(); + explicit GLSurface(const gfx::SurfaceConfiguration requested_configuration); // (Re)create the surface. TODO(apatrick): This is an ugly hack to allow the // EGL surface associated to be recreated without destroying the associated @@ -154,7 +163,8 @@ // Create a GL surface that renders directly to a view. static scoped_refptr<GLSurface> CreateViewGLSurface( - gfx::AcceleratedWidget window); + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration); #if defined(USE_OZONE) // Create a GL surface that renders directly into a window with surfaceless @@ -162,18 +172,24 @@ // be presented as an overlay. If surfaceless mode is not supported or // enabled it will return a null pointer. static scoped_refptr<GLSurface> CreateSurfacelessViewGLSurface( - gfx::AcceleratedWidget window); + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration); #endif // defined(USE_OZONE) // Create a GL surface used for offscreen rendering. static scoped_refptr<GLSurface> CreateOffscreenGLSurface( - const gfx::Size& size); + const gfx::Size& size, + const gfx::SurfaceConfiguration& requested_configuration); static GLSurface* GetCurrent(); // Called when the swap interval for the associated context changes. virtual void OnSetSwapInterval(int interval); + const gfx::SurfaceConfiguration get_surface_configuration() { + return surface_configuration_; + } + protected: virtual ~GLSurface(); static bool InitializeOneOffImplementation(GLImplementation impl, @@ -189,6 +205,8 @@ friend class base::RefCounted<GLSurface>; friend class GLContext; + gfx::SurfaceConfiguration surface_configuration_; + DISALLOW_COPY_AND_ASSIGN(GLSurface); };
diff --git a/ui/gl/gl_surface_android.cc b/ui/gl/gl_surface_android.cc index e87e9a8..38f1c81 100644 --- a/ui/gl/gl_surface_android.cc +++ b/ui/gl/gl_surface_android.cc
@@ -36,21 +36,25 @@ // static scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( - gfx::AcceleratedWidget window) { + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration) { CHECK_NE(kGLImplementationNone, GetGLImplementation()); if (GetGLImplementation() == kGLImplementationOSMesaGL) { - scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless()); + scoped_refptr<GLSurface> surface( + new GLSurfaceOSMesaHeadless(requested_configuration)); if (!surface->Initialize()) return NULL; return surface; } DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); if (window != kNullAcceleratedWidget) { - scoped_refptr<GLSurface> surface = new NativeViewGLSurfaceEGL(window); + scoped_refptr<GLSurface> surface = + new NativeViewGLSurfaceEGL(window, requested_configuration); if (surface->Initialize()) return surface; } else { - scoped_refptr<GLSurface> surface = new GLSurfaceStub(); + scoped_refptr<GLSurface> surface = + new GLSurfaceStub(requested_configuration); if (surface->Initialize()) return surface; } @@ -59,12 +63,13 @@ // static scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface( - const gfx::Size& size) { + const gfx::Size& size, + const gfx::SurfaceConfiguration& requested_configuration) { CHECK_NE(kGLImplementationNone, GetGLImplementation()); switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { - scoped_refptr<GLSurface> surface( - new GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, size)); + scoped_refptr<GLSurface> surface(new GLSurfaceOSMesa( + OSMesaSurfaceFormatBGRA, size, requested_configuration)); if (!surface->Initialize()) return NULL; @@ -74,9 +79,9 @@ scoped_refptr<GLSurface> surface; if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && (size.width() == 0 && size.height() == 0)) { - surface = new SurfacelessEGL(size); + surface = new SurfacelessEGL(size, requested_configuration); } else { - surface = new PbufferGLSurfaceEGL(size); + surface = new PbufferGLSurfaceEGL(size, requested_configuration); } if (!surface->Initialize())
diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index 4aa4365..9e67979 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc
@@ -47,7 +47,6 @@ namespace { -EGLConfig g_config; EGLDisplay g_display; EGLNativeDisplayType g_native_display_type; @@ -111,7 +110,9 @@ } // namespace -GLSurfaceEGL::GLSurfaceEGL() { +GLSurfaceEGL::GLSurfaceEGL( + const gfx::SurfaceConfiguration requested_configuration) + : GLSurface(requested_configuration) { ++g_num_surfaces; if (!g_initialized) { bool result = GLSurfaceEGL::InitializeOneOff(); @@ -120,6 +121,117 @@ } } +void* GetEGLConfig(const EGLNativeWindowType window, + const gfx::SurfaceConfiguration configuration, + bool allow_window_bit) { + // Choose an EGL configuration. + // On X this is only used for PBuffer surfaces. + EGLConfig config = {0}; + +#if defined(USE_X11) + XWindowAttributes win_attribs; + if (!XGetWindowAttributes(GLSurfaceEGL::GetNativeDisplay(), + window, + &win_attribs)) { + return nullptr; + } +#endif + + EGLint renderable_type = EGL_OPENGL_ES2_BIT; + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableUnsafeES3APIs)) { + renderable_type = EGL_OPENGL_ES3_BIT; + } + EGLint config_attribs[] = { + EGL_BUFFER_SIZE, configuration.alpha_bits + + configuration.red_bits + + configuration.green_bits + + configuration.blue_bits, + EGL_ALPHA_SIZE, configuration.alpha_bits, + EGL_BLUE_SIZE, configuration.blue_bits, + EGL_GREEN_SIZE, configuration.green_bits, + EGL_RED_SIZE, configuration.red_bits, + EGL_DEPTH_SIZE, configuration.depth_bits, + EGL_STENCIL_SIZE, configuration.stencil_bits, + EGL_RENDERABLE_TYPE, renderable_type, + EGL_SURFACE_TYPE, (allow_window_bit ? + (EGL_WINDOW_BIT | EGL_PBUFFER_BIT) : + EGL_PBUFFER_BIT), + EGL_NONE + }; + +#if defined(USE_OZONE) + config_attribs = + ui::SurfaceFactoryOzone::GetInstance()->GetEGLSurfaceProperties( + config_attribs); +#elif defined(USE_X11) + // Try matching the window depth with an alpha channel, + // because we're worried the destination alpha width could + // constrain blending precision. + const int kBufferSizeOffset = 1; + const int kAlphaSizeOffset = 3; + config_attribs[kBufferSizeOffset] = win_attribs.depth; +#endif + + EGLint num_configs; + if (!eglChooseConfig(g_display, + config_attribs, + NULL, + 0, + &num_configs)) { + LOG(ERROR) << "eglChooseConfig failed with error " + << GetLastEGLErrorString(); + return nullptr; + } + + if (!eglChooseConfig(g_display, + config_attribs, + &config, + 1, + &num_configs)) { + LOG(ERROR) << "eglChooseConfig failed with error " + << GetLastEGLErrorString(); + return nullptr; + } + +#if defined(USE_X11) + if (num_configs) { + EGLint config_depth; + if (!eglGetConfigAttrib(g_display, + config, + EGL_BUFFER_SIZE, + &config_depth)) { + LOG(ERROR) << "eglGetConfigAttrib failed with error " + << GetLastEGLErrorString(); + return nullptr; + } + + if (config_depth == win_attribs.depth) { + return config; + } + } + + // Try without an alpha channel. + config_attribs[kAlphaSizeOffset] = 0; + if (!eglChooseConfig(g_display, + config_attribs, + &config, + 1, + &num_configs)) { + LOG(ERROR) << "eglChooseConfig failed with error " + << GetLastEGLErrorString(); + return nullptr; + } +#endif + + if (num_configs == 0) { + LOG(ERROR) << "No suitable EGL configs found."; + return nullptr; + } + + return config; +} + bool GLSurfaceEGL::InitializeOneOff() { if (g_initialized) return true; @@ -138,58 +250,6 @@ return false; } - // Choose an EGL configuration. - // On X this is only used for PBuffer surfaces. - EGLint renderable_type = EGL_OPENGL_ES2_BIT; - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableUnsafeES3APIs)) { - renderable_type = EGL_OPENGL_ES3_BIT; - } - const EGLint kConfigAttribs[] = { - EGL_BUFFER_SIZE, 32, - EGL_ALPHA_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_RED_SIZE, 8, - EGL_RENDERABLE_TYPE, renderable_type, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, - EGL_NONE - }; - -#if defined(USE_OZONE) - const EGLint* config_attribs = - ui::SurfaceFactoryOzone::GetInstance()->GetEGLSurfaceProperties( - kConfigAttribs); -#else - const EGLint* config_attribs = kConfigAttribs; -#endif - - EGLint num_configs; - if (!eglChooseConfig(g_display, - config_attribs, - NULL, - 0, - &num_configs)) { - LOG(ERROR) << "eglChooseConfig failed with error " - << GetLastEGLErrorString(); - return false; - } - - if (num_configs == 0) { - LOG(ERROR) << "No suitable EGL configs found."; - return false; - } - - if (!eglChooseConfig(g_display, - config_attribs, - &g_config, - 1, - &num_configs)) { - LOG(ERROR) << "eglChooseConfig failed with error " - << GetLastEGLErrorString(); - return false; - } - g_egl_extensions = eglQueryString(g_display, EGL_EXTENSIONS); g_egl_create_context_robustness_supported = HasEGLExtension("EGL_EXT_create_context_robustness"); @@ -218,7 +278,8 @@ // EGL_KHR_surfaceless_context is supported but ensure // GL_OES_surfaceless_context is also supported. We need a current context // to query for supported GL extensions. - scoped_refptr<GLSurface> surface = new SurfacelessEGL(Size(1, 1)); + scoped_refptr<GLSurface> surface = new SurfacelessEGL( + Size(1, 1), SurfaceConfiguration()); scoped_refptr<GLContext> context = GLContext::CreateGLContext( NULL, surface.get(), PreferIntegratedGpu); if (!context->MakeCurrent(surface.get())) @@ -292,8 +353,11 @@ } } -NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) - : window_(window), +NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL( + EGLNativeWindowType window, + const gfx::SurfaceConfiguration requested_configuration) + : GLSurfaceEGL(requested_configuration), + window_(window), surface_(NULL), supports_post_sub_buffer_(false), config_(NULL), @@ -371,80 +435,11 @@ } EGLConfig NativeViewGLSurfaceEGL::GetConfig() { -#if !defined(USE_X11) - return g_config; -#else if (!config_) { - // Get a config compatible with the window DCHECK(window_); - XWindowAttributes win_attribs; - if (!XGetWindowAttributes(GetNativeDisplay(), window_, &win_attribs)) { - return NULL; - } - - // Try matching the window depth with an alpha channel, - // because we're worried the destination alpha width could - // constrain blending precision. - const int kBufferSizeOffset = 1; - const int kAlphaSizeOffset = 3; - EGLint config_attribs[] = { - EGL_BUFFER_SIZE, ~0, - EGL_ALPHA_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_RED_SIZE, 8, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, - EGL_NONE - }; - config_attribs[kBufferSizeOffset] = win_attribs.depth; - - EGLint num_configs; - if (!eglChooseConfig(g_display, - config_attribs, - &config_, - 1, - &num_configs)) { - LOG(ERROR) << "eglChooseConfig failed with error " - << GetLastEGLErrorString(); - return NULL; - } - - if (num_configs) { - EGLint config_depth; - if (!eglGetConfigAttrib(g_display, - config_, - EGL_BUFFER_SIZE, - &config_depth)) { - LOG(ERROR) << "eglGetConfigAttrib failed with error " - << GetLastEGLErrorString(); - return NULL; - } - - if (config_depth == win_attribs.depth) { - return config_; - } - } - - // Try without an alpha channel. - config_attribs[kAlphaSizeOffset] = 0; - if (!eglChooseConfig(g_display, - config_attribs, - &config_, - 1, - &num_configs)) { - LOG(ERROR) << "eglChooseConfig failed with error " - << GetLastEGLErrorString(); - return NULL; - } - - if (num_configs == 0) { - LOG(ERROR) << "No suitable EGL configs found."; - return NULL; - } + config_ = GetEGLConfig(window_, this->get_surface_configuration(), true); } return config_; -#endif } bool NativeViewGLSurfaceEGL::IsOffscreen() { @@ -548,9 +543,13 @@ #endif } -PbufferGLSurfaceEGL::PbufferGLSurfaceEGL(const gfx::Size& size) - : size_(size), - surface_(NULL) { +PbufferGLSurfaceEGL::PbufferGLSurfaceEGL( + const gfx::Size& size, + const gfx::SurfaceConfiguration requested_configuration) + : GLSurfaceEGL(requested_configuration), + size_(size), + surface_(nullptr), + config_(nullptr) { // Some implementations of Pbuffer do not support having a 0 size. For such // cases use a (1, 1) surface. if (size_.GetArea() == 0) @@ -603,7 +602,12 @@ } EGLConfig PbufferGLSurfaceEGL::GetConfig() { - return g_config; + if (!config_) { + config_ = GetEGLConfig((EGLNativeWindowType)nullptr, + this->get_surface_configuration(), + false); + } + return config_; } bool PbufferGLSurfaceEGL::IsOffscreen() { @@ -673,8 +677,10 @@ Destroy(); } -SurfacelessEGL::SurfacelessEGL(const gfx::Size& size) - : size_(size) { +SurfacelessEGL::SurfacelessEGL( + const gfx::Size& size, + const gfx::SurfaceConfiguration requested_configuration) + : GLSurfaceEGL(requested_configuration), size_(size) { } bool SurfacelessEGL::Initialize() { @@ -685,7 +691,7 @@ } EGLConfig SurfacelessEGL::GetConfig() { - return g_config; + return NULL; } bool SurfacelessEGL::IsOffscreen() {
diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h index a80843e..9bf2a2d 100644 --- a/ui/gl/gl_surface_egl.h +++ b/ui/gl/gl_surface_egl.h
@@ -22,7 +22,8 @@ // Interface for EGL surface. class GL_EXPORT GLSurfaceEGL : public GLSurface { public: - GLSurfaceEGL(); + explicit GLSurfaceEGL( + const gfx::SurfaceConfiguration requested_configuration); // Implement GLSurface. void DestroyAndTerminateDisplay() override; @@ -50,7 +51,9 @@ // Encapsulates an EGL surface bound to a view. class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL { public: - explicit NativeViewGLSurfaceEGL(EGLNativeWindowType window); + NativeViewGLSurfaceEGL( + EGLNativeWindowType window, + const gfx::SurfaceConfiguration requested_configuration); // Implement GLSurface. EGLConfig GetConfig() override; @@ -93,7 +96,8 @@ // Encapsulates a pbuffer EGL surface. class GL_EXPORT PbufferGLSurfaceEGL : public GLSurfaceEGL { public: - explicit PbufferGLSurfaceEGL(const gfx::Size& size); + PbufferGLSurfaceEGL(const gfx::Size& size, + const gfx::SurfaceConfiguration requested_configuration); // Implement GLSurface. EGLConfig GetConfig() override; @@ -112,6 +116,7 @@ private: gfx::Size size_; EGLSurface surface_; + EGLConfig config_; DISALLOW_COPY_AND_ASSIGN(PbufferGLSurfaceEGL); }; @@ -121,7 +126,8 @@ // need to create a dummy EGLsurface in case we render to client API targets. class GL_EXPORT SurfacelessEGL : public GLSurfaceEGL { public: - explicit SurfacelessEGL(const gfx::Size& size); + SurfacelessEGL(const gfx::Size& size, + SurfaceConfiguration requested_configuration); // Implement GLSurface. EGLConfig GetConfig() override;
diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc index d66078c..2a52fc7 100644 --- a/ui/gl/gl_surface_glx.cc +++ b/ui/gl/gl_surface_glx.cc
@@ -317,7 +317,10 @@ } // namespace -GLSurfaceGLX::GLSurfaceGLX() {} +GLSurfaceGLX::GLSurfaceGLX( + const gfx::SurfaceConfiguration& requested_configuration) + : GLSurface(requested_configuration) { +} bool GLSurfaceGLX::InitializeOneOff() { static bool initialized = false; @@ -404,8 +407,11 @@ GLSurfaceGLX::~GLSurfaceGLX() {} -NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window) - : parent_window_(window), +NativeViewGLSurfaceGLX::NativeViewGLSurfaceGLX( + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration) + : GLSurfaceGLX(requested_configuration), + parent_window_(window), window_(0), config_(NULL) { } @@ -529,6 +535,11 @@ // use when creating the window in the first place. Then we can // pass that FBConfig down rather than attempting to reconstitute // it. + // + // TODO(iansf): Perhaps instead of kbr's suggestion above, we can + // now use GLSurface::GetSurfaceConfiguration to use the returned + // gfx::SurfaceConfiguration with glXChooseFBConfig in a manner + // similar to that used in NativeViewGLSurfaceEGL::GetConfig. XWindowAttributes attributes; if (!XGetWindowAttributes( @@ -590,8 +601,11 @@ Destroy(); } -PbufferGLSurfaceGLX::PbufferGLSurfaceGLX(const gfx::Size& size) - : size_(size), +PbufferGLSurfaceGLX::PbufferGLSurfaceGLX( + const gfx::Size& size, + const gfx::SurfaceConfiguration& requested_configuration) + : GLSurfaceGLX(requested_configuration), + size_(size), config_(NULL), pbuffer_(0) { // Some implementations of Pbuffer do not support having a 0 size. For such
diff --git a/ui/gl/gl_surface_glx.h b/ui/gl/gl_surface_glx.h index c1fca60..d8fa9a4 100644 --- a/ui/gl/gl_surface_glx.h +++ b/ui/gl/gl_surface_glx.h
@@ -21,7 +21,8 @@ // Base class for GLX surfaces. class GL_EXPORT GLSurfaceGLX : public GLSurface { public: - GLSurfaceGLX(); + explicit GLSurfaceGLX( + const gfx::SurfaceConfiguration& requested_configuration); static bool InitializeOneOff(); @@ -52,7 +53,9 @@ class GL_EXPORT NativeViewGLSurfaceGLX : public GLSurfaceGLX, public ui::PlatformEventDispatcher { public: - explicit NativeViewGLSurfaceGLX(gfx::AcceleratedWidget window); + NativeViewGLSurfaceGLX( + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration); // Implement GLSurfaceGLX. bool Initialize() override; @@ -95,7 +98,9 @@ // A surface used to render to an offscreen pbuffer. class GL_EXPORT PbufferGLSurfaceGLX : public GLSurfaceGLX { public: - explicit PbufferGLSurfaceGLX(const gfx::Size& size); + PbufferGLSurfaceGLX( + const gfx::Size& size, + const gfx::SurfaceConfiguration& requested_configuration); // Implement GLSurfaceGLX. bool Initialize() override;
diff --git a/ui/gl/gl_surface_osmesa.cc b/ui/gl/gl_surface_osmesa.cc index 7f1b1ad..2efe12b 100644 --- a/ui/gl/gl_surface_osmesa.cc +++ b/ui/gl/gl_surface_osmesa.cc
@@ -12,9 +12,11 @@ namespace gfx { -GLSurfaceOSMesa::GLSurfaceOSMesa(OSMesaSurfaceFormat format, - const gfx::Size& size) - : size_(size) { +GLSurfaceOSMesa::GLSurfaceOSMesa( + OSMesaSurfaceFormat format, + const gfx::Size& size, + const gfx::SurfaceConfiguration requested_configuration) + : GLSurface(requested_configuration), size_(size) { switch (format) { case OSMesaSurfaceFormatBGRA: format_ = OSMESA_BGRA; @@ -37,6 +39,14 @@ buffer_.reset(); } +void* GLSurfaceOSMesa::GetConfig() { + // TODO(iansf): Possibly choose a configuration in a manner similar to + // NativeViewGLSurfaceEGL::GetConfig, using the gfx::SurfaceConfiguration + // returned by GLSurface::GetSurfaceConfiguration. + NOTIMPLEMENTED(); + return NULL; +} + bool GLSurfaceOSMesa::Resize(const gfx::Size& new_size) { scoped_ptr<ui::ScopedMakeCurrent> scoped_make_current; GLContext* current_context = GLContext::GetCurrent(); @@ -109,8 +119,19 @@ bool GLSurfaceOSMesaHeadless::SwapBuffers() { return true; } -GLSurfaceOSMesaHeadless::GLSurfaceOSMesaHeadless() - : GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, gfx::Size(1, 1)) { +GLSurfaceOSMesaHeadless::GLSurfaceOSMesaHeadless( + const gfx::SurfaceConfiguration requested_configuration) + : GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, + gfx::Size(1, 1), + requested_configuration) { +} + +void* GLSurfaceOSMesaHeadless::GetConfig() { + // TODO(iansf): Possibly choose a configuration in a manner similar to + // NativeViewGLSurfaceEGL::GetConfig, using the gfx::SurfaceConfiguration + // returned by GLSurface::GetSurfaceConfiguration. + NOTIMPLEMENTED(); + return NULL; } GLSurfaceOSMesaHeadless::~GLSurfaceOSMesaHeadless() { Destroy(); }
diff --git a/ui/gl/gl_surface_osmesa.h b/ui/gl/gl_surface_osmesa.h index cd65e65..7484063 100644 --- a/ui/gl/gl_surface_osmesa.h +++ b/ui/gl/gl_surface_osmesa.h
@@ -18,7 +18,9 @@ // surfaces can be resized and resizing preserves the contents. class GL_EXPORT GLSurfaceOSMesa : public GLSurface { public: - GLSurfaceOSMesa(OSMesaSurfaceFormat format, const gfx::Size& size); + GLSurfaceOSMesa(OSMesaSurfaceFormat format, + const gfx::Size& size, + const gfx::SurfaceConfiguration requested_configuration); // Implement GLSurface. bool Initialize() override; @@ -29,6 +31,7 @@ gfx::Size GetSize() override; void* GetHandle() override; unsigned GetFormat() override; + void* GetConfig() override; protected: ~GLSurfaceOSMesa() override; @@ -46,10 +49,12 @@ // provider is not available. class GLSurfaceOSMesaHeadless : public GLSurfaceOSMesa { public: - explicit GLSurfaceOSMesaHeadless(); + explicit GLSurfaceOSMesaHeadless( + const gfx::SurfaceConfiguration requested_configuration); bool IsOffscreen() override; bool SwapBuffers() override; + void* GetConfig() override; protected: ~GLSurfaceOSMesaHeadless() override;
diff --git a/ui/gl/gl_surface_stub.cc b/ui/gl/gl_surface_stub.cc index a27d2af..70230fc 100644 --- a/ui/gl/gl_surface_stub.cc +++ b/ui/gl/gl_surface_stub.cc
@@ -6,6 +6,11 @@ namespace gfx { +GLSurfaceStub::GLSurfaceStub( + const gfx::SurfaceConfiguration requested_configuration) + : GLSurface(requested_configuration) { +} + void GLSurfaceStub::Destroy() { }
diff --git a/ui/gl/gl_surface_stub.h b/ui/gl/gl_surface_stub.h index 1bdd32a..f35e716 100644 --- a/ui/gl/gl_surface_stub.h +++ b/ui/gl/gl_surface_stub.h
@@ -12,6 +12,9 @@ // A GLSurface that does nothing for unit tests. class GL_EXPORT GLSurfaceStub : public GLSurface { public: + explicit GLSurfaceStub( + const gfx::SurfaceConfiguration requested_configuration); + void SetSize(const gfx::Size& size) { size_ = size; } // Implement GLSurface.
diff --git a/ui/gl/gl_surface_x11.cc b/ui/gl/gl_surface_x11.cc index a384147..efbaf60 100644 --- a/ui/gl/gl_surface_x11.cc +++ b/ui/gl/gl_surface_x11.cc
@@ -23,7 +23,9 @@ // view. class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa { public: - explicit NativeViewGLSurfaceOSMesa(gfx::AcceleratedWidget window); + NativeViewGLSurfaceOSMesa( + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration); static bool InitializeOneOff(); @@ -77,8 +79,11 @@ } NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa( - gfx::AcceleratedWidget window) - : GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, gfx::Size(1, 1)), + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration) + : GLSurfaceOSMesa(OSMesaSurfaceFormatBGRA, + gfx::Size(1, 1), + requested_configuration), xdisplay_(gfx::GetXDisplay()), window_graphics_context_(0), window_(window), @@ -272,19 +277,21 @@ } scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( - gfx::AcceleratedWidget window) { + gfx::AcceleratedWidget window, + const gfx::SurfaceConfiguration& requested_configuration) { TRACE_EVENT0("gpu", "GLSurface::CreateViewGLSurface"); switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { scoped_refptr<GLSurface> surface( - new NativeViewGLSurfaceOSMesa(window)); + new NativeViewGLSurfaceOSMesa(window, requested_configuration)); if (!surface->Initialize()) return NULL; return surface; } case kGLImplementationDesktopGL: { - scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceGLX(window)); + scoped_refptr<GLSurface> surface( + new NativeViewGLSurfaceGLX(window, requested_configuration)); if (!surface->Initialize()) return NULL; @@ -292,14 +299,15 @@ } case kGLImplementationEGLGLES2: { DCHECK(window != gfx::kNullAcceleratedWidget); - scoped_refptr<GLSurface> surface(new NativeViewGLSurfaceEGL(window)); + scoped_refptr<GLSurface> surface( + new NativeViewGLSurfaceEGL(window, requested_configuration)); if (!surface->Initialize()) return NULL; return surface; } case kGLImplementationMockGL: - return new GLSurfaceStub; + return new GLSurfaceStub(requested_configuration); default: NOTREACHED(); return NULL; @@ -307,33 +315,38 @@ } scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface( - const gfx::Size& size) { + const gfx::Size& size, + const gfx::SurfaceConfiguration& requested_configuration) { TRACE_EVENT0("gpu", "GLSurface::CreateOffscreenGLSurface"); switch (GetGLImplementation()) { case kGLImplementationOSMesaGL: { scoped_refptr<GLSurface> surface( - new GLSurfaceOSMesa(OSMesaSurfaceFormatRGBA, size)); + new GLSurfaceOSMesa(OSMesaSurfaceFormatRGBA, + size, + requested_configuration)); if (!surface->Initialize()) return NULL; return surface; } case kGLImplementationDesktopGL: { - scoped_refptr<GLSurface> surface(new PbufferGLSurfaceGLX(size)); + scoped_refptr<GLSurface> surface( + new PbufferGLSurfaceGLX(size, requested_configuration)); if (!surface->Initialize()) return NULL; return surface; } case kGLImplementationEGLGLES2: { - scoped_refptr<GLSurface> surface(new PbufferGLSurfaceEGL(size)); + scoped_refptr<GLSurface> surface( + new PbufferGLSurfaceEGL(size, requested_configuration)); if (!surface->Initialize()) return NULL; return surface; } case kGLImplementationMockGL: - return new GLSurfaceStub; + return new GLSurfaceStub(requested_configuration); default: NOTREACHED(); return NULL;