| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/android/in_process/synchronous_compositor_factory_impl
.h" | 5 #include "content/browser/android/in_process/synchronous_compositor_factory_impl
.h" |
| 6 | 6 |
| 7 #include "content/browser/android/in_process/synchronous_compositor_output_surfa
ce.h" | 7 #include "content/browser/android/in_process/synchronous_compositor_output_surfa
ce.h" |
| 8 #include "content/public/browser/browser_thread.h" | 8 #include "content/public/browser/browser_thread.h" |
| 9 #include "gpu/command_buffer/client/gl_in_process_context.h" | 9 #include "gpu/command_buffer/client/gl_in_process_context.h" |
| 10 #include "ui/gl/android/surface_texture.h" | 10 #include "ui/gl/android/surface_texture.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 attributes.depth = false; | 25 attributes.depth = false; |
| 26 attributes.stencil = false; | 26 attributes.stencil = false; |
| 27 attributes.shareResources = true; | 27 attributes.shareResources = true; |
| 28 attributes.noAutomaticFlushes = true; | 28 attributes.noAutomaticFlushes = true; |
| 29 | 29 |
| 30 return attributes; | 30 return attributes; |
| 31 } | 31 } |
| 32 | 32 |
| 33 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; | 33 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; |
| 34 | 34 |
| 35 scoped_ptr<gpu::GLInProcessContext> CreateContextWithAttributes( | 35 scoped_ptr<gpu::GLInProcessContext> CreateOffscreenContext( |
| 36 scoped_refptr<gfx::GLSurface> surface, | |
| 37 scoped_refptr<gpu::InProcessCommandBuffer::Service> service, | |
| 38 gpu::GLInProcessContext* share_context, | |
| 39 const blink::WebGraphicsContext3D::Attributes& attributes) { | 36 const blink::WebGraphicsContext3D::Attributes& attributes) { |
| 40 const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; | 37 const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; |
| 41 | 38 |
| 42 if (!surface) | |
| 43 surface = gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(1, 1)); | |
| 44 | |
| 45 gpu::GLInProcessContextAttribs in_process_attribs; | 39 gpu::GLInProcessContextAttribs in_process_attribs; |
| 46 WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes( | 40 WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes( |
| 47 attributes, &in_process_attribs); | 41 attributes, &in_process_attribs); |
| 48 in_process_attribs.lose_context_when_out_of_memory = 1; | 42 in_process_attribs.lose_context_when_out_of_memory = 1; |
| 43 |
| 49 scoped_ptr<gpu::GLInProcessContext> context( | 44 scoped_ptr<gpu::GLInProcessContext> context( |
| 50 gpu::GLInProcessContext::CreateWithSurface( | 45 gpu::GLInProcessContext::Create(NULL /* service */, |
| 51 surface, service, share_context, in_process_attribs, gpu_preference)); | 46 NULL /* surface */, |
| 47 true /* is_offscreen */, |
| 48 gfx::kNullAcceleratedWidget, |
| 49 gfx::Size(1, 1), |
| 50 NULL /* share_context */, |
| 51 false /* share_resources */, |
| 52 in_process_attribs, |
| 53 gpu_preference)); |
| 52 return context.Pass(); | 54 return context.Pass(); |
| 53 } | 55 } |
| 54 | 56 |
| 55 scoped_ptr<gpu::GLInProcessContext> CreateContext( | 57 scoped_ptr<gpu::GLInProcessContext> CreateContext( |
| 56 scoped_refptr<gfx::GLSurface> surface, | 58 scoped_refptr<gfx::GLSurface> surface, |
| 57 scoped_refptr<gpu::InProcessCommandBuffer::Service> service, | 59 scoped_refptr<gpu::InProcessCommandBuffer::Service> service, |
| 58 gpu::GLInProcessContext* share_context) { | 60 gpu::GLInProcessContext* share_context) { |
| 59 return CreateContextWithAttributes( | 61 const gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu; |
| 60 surface, service, share_context, GetDefaultAttribs()); | 62 gpu::GLInProcessContextAttribs in_process_attribs; |
| 63 WebGraphicsContext3DInProcessCommandBufferImpl::ConvertAttributes( |
| 64 GetDefaultAttribs(), &in_process_attribs); |
| 65 in_process_attribs.lose_context_when_out_of_memory = 1; |
| 66 |
| 67 |
| 68 bool is_offscreen = false; |
| 69 gfx::Size size(1, 1); |
| 70 if (surface) { |
| 71 is_offscreen = surface->IsOffscreen(); |
| 72 size = surface->GetSize(); |
| 73 } |
| 74 |
| 75 scoped_ptr<gpu::GLInProcessContext> context( |
| 76 gpu::GLInProcessContext::Create(service, |
| 77 surface, |
| 78 is_offscreen, |
| 79 gfx::kNullAcceleratedWidget, |
| 80 size, |
| 81 share_context, |
| 82 false /* share_resources */, |
| 83 in_process_attribs, |
| 84 gpu_preference)); |
| 85 return context.Pass(); |
| 61 } | 86 } |
| 62 | 87 |
| 63 scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> WrapContext( | 88 scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl> WrapContext( |
| 64 scoped_ptr<gpu::GLInProcessContext> context) { | 89 scoped_ptr<gpu::GLInProcessContext> context) { |
| 65 if (!context.get()) | 90 if (!context.get()) |
| 66 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(); | 91 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>(); |
| 67 | 92 |
| 68 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>( | 93 return scoped_ptr<WebGraphicsContext3DInProcessCommandBufferImpl>( |
| 69 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( | 94 WebGraphicsContext3DInProcessCommandBufferImpl::WrapContext( |
| 70 context.Pass(), GetDefaultAttribs())); | 95 context.Pass(), GetDefaultAttribs())); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 100 gpu::GLInProcessContext* gl_in_process_context_; | 125 gpu::GLInProcessContext* gl_in_process_context_; |
| 101 | 126 |
| 102 DISALLOW_COPY_AND_ASSIGN(VideoContextProvider); | 127 DISALLOW_COPY_AND_ASSIGN(VideoContextProvider); |
| 103 }; | 128 }; |
| 104 | 129 |
| 105 } // namespace | 130 } // namespace |
| 106 | 131 |
| 107 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; | 132 using webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl; |
| 108 | 133 |
| 109 SynchronousCompositorFactoryImpl::SynchronousCompositorFactoryImpl() | 134 SynchronousCompositorFactoryImpl::SynchronousCompositorFactoryImpl() |
| 110 : wrapped_gl_context_for_compositor_thread_(NULL), | 135 : num_hardware_compositors_(0) { |
| 111 num_hardware_compositors_(0) { | |
| 112 SynchronousCompositorFactory::SetInstance(this); | 136 SynchronousCompositorFactory::SetInstance(this); |
| 113 } | 137 } |
| 114 | 138 |
| 115 SynchronousCompositorFactoryImpl::~SynchronousCompositorFactoryImpl() {} | 139 SynchronousCompositorFactoryImpl::~SynchronousCompositorFactoryImpl() {} |
| 116 | 140 |
| 117 scoped_refptr<base::MessageLoopProxy> | 141 scoped_refptr<base::MessageLoopProxy> |
| 118 SynchronousCompositorFactoryImpl::GetCompositorMessageLoop() { | 142 SynchronousCompositorFactoryImpl::GetCompositorMessageLoop() { |
| 119 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | 143 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); |
| 120 } | 144 } |
| 121 | 145 |
| 122 scoped_ptr<cc::OutputSurface> | 146 scoped_ptr<cc::OutputSurface> |
| 123 SynchronousCompositorFactoryImpl::CreateOutputSurface(int routing_id) { | 147 SynchronousCompositorFactoryImpl::CreateOutputSurface(int routing_id) { |
| 124 scoped_ptr<SynchronousCompositorOutputSurface> output_surface( | 148 scoped_ptr<SynchronousCompositorOutputSurface> output_surface( |
| 125 new SynchronousCompositorOutputSurface(routing_id)); | 149 new SynchronousCompositorOutputSurface(routing_id)); |
| 126 return output_surface.PassAs<cc::OutputSurface>(); | 150 return output_surface.PassAs<cc::OutputSurface>(); |
| 127 } | 151 } |
| 128 | 152 |
| 129 InputHandlerManagerClient* | 153 InputHandlerManagerClient* |
| 130 SynchronousCompositorFactoryImpl::GetInputHandlerManagerClient() { | 154 SynchronousCompositorFactoryImpl::GetInputHandlerManagerClient() { |
| 131 return synchronous_input_event_filter(); | 155 return synchronous_input_event_filter(); |
| 132 } | 156 } |
| 133 | 157 |
| 134 scoped_refptr<ContextProviderWebContext> SynchronousCompositorFactoryImpl:: | 158 scoped_refptr<ContextProviderWebContext> SynchronousCompositorFactoryImpl:: |
| 135 GetSharedOffscreenContextProviderForMainThread() { | 159 GetSharedOffscreenContextProviderForMainThread() { |
| 136 bool failed = false; | 160 bool failed = false; |
| 137 if ((!offscreen_context_for_main_thread_.get() || | 161 if ((!offscreen_context_for_main_thread_.get() || |
| 138 offscreen_context_for_main_thread_->DestroyedOnMainThread())) { | 162 offscreen_context_for_main_thread_->DestroyedOnMainThread())) { |
| 139 scoped_ptr<gpu::GLInProcessContext> context = | 163 scoped_ptr<gpu::GLInProcessContext> context = |
| 140 CreateContext(NULL, NULL, NULL); | 164 CreateOffscreenContext(GetDefaultAttribs()); |
| 141 offscreen_context_for_main_thread_ = | 165 offscreen_context_for_main_thread_ = |
| 142 webkit::gpu::ContextProviderInProcess::Create( | 166 webkit::gpu::ContextProviderInProcess::Create( |
| 143 WrapContext(context.Pass()), | 167 WrapContext(context.Pass()), |
| 144 "Compositor-Offscreen-main-thread"); | 168 "Compositor-Offscreen-main-thread"); |
| 145 failed = !offscreen_context_for_main_thread_.get() || | 169 failed = !offscreen_context_for_main_thread_.get() || |
| 146 !offscreen_context_for_main_thread_->BindToCurrentThread(); | 170 !offscreen_context_for_main_thread_->BindToCurrentThread(); |
| 147 } | 171 } |
| 148 | 172 |
| 149 if (failed) { | 173 if (failed) { |
| 150 offscreen_context_for_main_thread_ = NULL; | 174 offscreen_context_for_main_thread_ = NULL; |
| 151 } | 175 } |
| 152 return offscreen_context_for_main_thread_; | 176 return offscreen_context_for_main_thread_; |
| 153 } | 177 } |
| 154 | 178 |
| 155 // This is called on the renderer compositor impl thread (InitializeHwDraw) in | |
| 156 // order to support Android WebView synchronously enable and disable hardware | |
| 157 // mode multiple times in the same task. | |
| 158 scoped_refptr<cc::ContextProvider> SynchronousCompositorFactoryImpl:: | |
| 159 GetOffscreenContextProviderForCompositorThread() { | |
| 160 DCHECK(service_); | |
| 161 bool failed = false; | |
| 162 if (!offscreen_context_for_compositor_thread_.get() || | |
| 163 offscreen_context_for_compositor_thread_->DestroyedOnMainThread()) { | |
| 164 scoped_ptr<gpu::GLInProcessContext> context = | |
| 165 CreateContext(new gfx::GLSurfaceStub, service_, NULL); | |
| 166 wrapped_gl_context_for_compositor_thread_ = context.get(); | |
| 167 offscreen_context_for_compositor_thread_ = | |
| 168 webkit::gpu::ContextProviderInProcess::Create( | |
| 169 WrapContext(context.Pass()), | |
| 170 "Compositor-Offscreen-compositor-thread"); | |
| 171 failed = !offscreen_context_for_compositor_thread_.get() || | |
| 172 !offscreen_context_for_compositor_thread_->BindToCurrentThread(); | |
| 173 } | |
| 174 if (failed) { | |
| 175 offscreen_context_for_compositor_thread_ = NULL; | |
| 176 wrapped_gl_context_for_compositor_thread_ = NULL; | |
| 177 } | |
| 178 return offscreen_context_for_compositor_thread_; | |
| 179 } | |
| 180 | |
| 181 scoped_refptr<cc::ContextProvider> SynchronousCompositorFactoryImpl:: | 179 scoped_refptr<cc::ContextProvider> SynchronousCompositorFactoryImpl:: |
| 182 CreateOnscreenContextProviderForCompositorThread( | 180 CreateOnscreenContextProviderForCompositorThread( |
| 183 scoped_refptr<gfx::GLSurface> surface) { | 181 scoped_refptr<gfx::GLSurface> surface) { |
| 184 DCHECK(surface); | 182 DCHECK(surface); |
| 185 DCHECK(service_); | 183 DCHECK(service_); |
| 186 DCHECK(wrapped_gl_context_for_compositor_thread_); | |
| 187 | 184 |
| 185 if (!share_context_.get()) |
| 186 share_context_ = CreateContext(NULL, service_, NULL); |
| 188 return webkit::gpu::ContextProviderInProcess::Create( | 187 return webkit::gpu::ContextProviderInProcess::Create( |
| 189 WrapContext(CreateContext( | 188 WrapContext(CreateContext(surface, service_, share_context_.get())), |
| 190 surface, service_, wrapped_gl_context_for_compositor_thread_)), | |
| 191 "Compositor-Onscreen"); | 189 "Compositor-Onscreen"); |
| 192 } | 190 } |
| 193 | 191 |
| 194 scoped_refptr<StreamTextureFactory> | 192 scoped_refptr<StreamTextureFactory> |
| 195 SynchronousCompositorFactoryImpl::CreateStreamTextureFactory(int view_id) { | 193 SynchronousCompositorFactoryImpl::CreateStreamTextureFactory(int view_id) { |
| 196 scoped_refptr<StreamTextureFactorySynchronousImpl> factory( | 194 scoped_refptr<StreamTextureFactorySynchronousImpl> factory( |
| 197 StreamTextureFactorySynchronousImpl::Create( | 195 StreamTextureFactorySynchronousImpl::Create( |
| 198 base::Bind( | 196 base::Bind( |
| 199 &SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory, | 197 &SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory, |
| 200 base::Unretained(this)), | 198 base::Unretained(this)), |
| 201 view_id)); | 199 view_id)); |
| 202 return factory; | 200 return factory; |
| 203 } | 201 } |
| 204 | 202 |
| 205 blink::WebGraphicsContext3D* | 203 blink::WebGraphicsContext3D* |
| 206 SynchronousCompositorFactoryImpl::CreateOffscreenGraphicsContext3D( | 204 SynchronousCompositorFactoryImpl::CreateOffscreenGraphicsContext3D( |
| 207 const blink::WebGraphicsContext3D::Attributes& attributes) { | 205 const blink::WebGraphicsContext3D::Attributes& attributes) { |
| 208 return WrapContext(CreateContextWithAttributes(NULL, NULL, NULL, attributes)) | 206 return WrapContext(CreateOffscreenContext(attributes)).release(); |
| 209 .release(); | |
| 210 } | 207 } |
| 211 | 208 |
| 212 void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw() { | 209 void SynchronousCompositorFactoryImpl::CompositorInitializedHardwareDraw() { |
| 213 base::AutoLock lock(num_hardware_compositor_lock_); | 210 base::AutoLock lock(num_hardware_compositor_lock_); |
| 214 num_hardware_compositors_++; | 211 num_hardware_compositors_++; |
| 215 } | 212 } |
| 216 | 213 |
| 217 void SynchronousCompositorFactoryImpl::CompositorReleasedHardwareDraw() { | 214 void SynchronousCompositorFactoryImpl::CompositorReleasedHardwareDraw() { |
| 218 base::AutoLock lock(num_hardware_compositor_lock_); | 215 base::AutoLock lock(num_hardware_compositor_lock_); |
| 219 DCHECK_GT(num_hardware_compositors_, 0u); | 216 DCHECK_GT(num_hardware_compositors_, 0u); |
| 220 num_hardware_compositors_--; | 217 num_hardware_compositors_--; |
| 221 } | 218 } |
| 222 | 219 |
| 223 bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() { | 220 bool SynchronousCompositorFactoryImpl::CanCreateMainThreadContext() { |
| 224 base::AutoLock lock(num_hardware_compositor_lock_); | 221 base::AutoLock lock(num_hardware_compositor_lock_); |
| 225 return num_hardware_compositors_ > 0; | 222 return num_hardware_compositors_ > 0; |
| 226 } | 223 } |
| 227 | 224 |
| 228 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> | 225 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> |
| 229 SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory() { | 226 SynchronousCompositorFactoryImpl::TryCreateStreamTextureFactory() { |
| 230 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> | 227 scoped_refptr<StreamTextureFactorySynchronousImpl::ContextProvider> |
| 231 context_provider; | 228 context_provider; |
| 232 // This check only guarantees the main thread context is created after | 229 // This check only guarantees the main thread context is created after |
| 233 // a compositor did successfully initialize hardware draw in the past. | 230 // a compositor did successfully initialize hardware draw in the past. |
| 234 // In particular this does not guarantee that the main thread context | 231 // In particular this does not guarantee that the main thread context |
| 235 // will fail creation when all compositors release hardware draw. | 232 // will fail creation when all compositors release hardware draw. |
| 236 if (CanCreateMainThreadContext() && !video_context_provider_) { | 233 if (CanCreateMainThreadContext() && !video_context_provider_) { |
| 237 DCHECK(service_); | 234 DCHECK(service_); |
| 238 DCHECK(wrapped_gl_context_for_compositor_thread_); | 235 DCHECK(share_context_.get()); |
| 239 | 236 |
| 240 video_context_provider_ = new VideoContextProvider( | 237 video_context_provider_ = new VideoContextProvider( |
| 241 CreateContext(new gfx::GLSurfaceStub, | 238 CreateContext(NULL, service_, share_context_.get())); |
| 242 service_, | |
| 243 wrapped_gl_context_for_compositor_thread_)); | |
| 244 } | 239 } |
| 245 return video_context_provider_; | 240 return video_context_provider_; |
| 246 } | 241 } |
| 247 | 242 |
| 248 void SynchronousCompositorFactoryImpl::SetDeferredGpuService( | 243 void SynchronousCompositorFactoryImpl::SetDeferredGpuService( |
| 249 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) { | 244 scoped_refptr<gpu::InProcessCommandBuffer::Service> service) { |
| 250 DCHECK(!service_); | 245 DCHECK(!service_); |
| 251 service_ = service; | 246 service_ = service; |
| 252 } | 247 } |
| 253 | 248 |
| 254 } // namespace content | 249 } // namespace content |
| OLD | NEW |