Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/android/blimp/chrome_compositor_dependencies.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/command_line.h" | |
| 9 #include "cc/output/context_provider.h" | |
| 10 #include "content/public/common/content_switches.h" | |
| 11 #include "gpu/command_buffer/client/gles2_interface.h" | |
| 12 #include "gpu/command_buffer/client/shared_memory_limits.h" | |
| 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | |
| 14 #include "ui/android/context_provider_factory.h" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 void OnCompositorContextCreated( | |
| 19 const blimp::client::CompositorDependencies::ContextProviderCallback& | |
| 20 callback, | |
| 21 const scoped_refptr<cc::ContextProvider>& worker_context, | |
| 22 const scoped_refptr<cc::ContextProvider>& compositor_context) { | |
| 23 blimp::client::CompositorDependencies::ContextProviders context_providers; | |
| 24 context_providers.compositor_context_provider = std::move(compositor_context); | |
| 25 context_providers.worker_context_provider = std::move(worker_context); | |
| 26 callback.Run(context_providers); | |
| 27 } | |
| 28 | |
| 29 gpu::gles2::ContextCreationAttribHelper | |
| 30 GetOffscreenContextCreationAttributes() { | |
| 31 gpu::gles2::ContextCreationAttribHelper attributes; | |
| 32 attributes.alpha_size = -1; | |
| 33 attributes.depth_size = 0; | |
| 34 attributes.stencil_size = 0; | |
| 35 attributes.samples = 0; | |
| 36 attributes.sample_buffers = 0; | |
| 37 attributes.bind_generates_resource = false; | |
| 38 attributes.lose_context_when_out_of_memory = true; | |
| 39 return attributes; | |
| 40 } | |
| 41 | |
| 42 bool IsAsyncWorkerContextEnabled() { | |
| 43 const base::CommandLine& command_line = | |
| 44 *base::CommandLine::ForCurrentProcess(); | |
| 45 | |
| 46 if (command_line.HasSwitch(switches::kDisableGpuAsyncWorkerContext)) | |
| 47 return false; | |
| 48 else if (command_line.HasSwitch(switches::kEnableGpuAsyncWorkerContext)) | |
| 49 return true; | |
| 50 | |
| 51 return false; | |
| 52 } | |
| 53 | |
| 54 } // namespace | |
| 55 | |
| 56 ChromeCompositorDependencies::ChromeCompositorDependencies( | |
| 57 ui::ContextProviderFactory* context_provider_factory) | |
| 58 : context_provider_factory_(context_provider_factory), | |
| 59 worker_context_request_pending_(false), | |
| 60 weak_factory_(this) { | |
| 61 DCHECK(context_provider_factory_); | |
| 62 } | |
| 63 | |
| 64 ChromeCompositorDependencies::~ChromeCompositorDependencies() = default; | |
| 65 | |
| 66 cc::LayerTreeSettings* ChromeCompositorDependencies::GetLayerTreeSettings() { | |
| 67 // MAKE THE SETTINGS!!!!! | |
|
David Trainor- moved to gerrit
2016/08/31 00:28:58
yes plz! In another patch maybe pull out the Comp
Khushal
2016/08/31 21:22:51
Done. I just moved it to internal for now, when Ch
| |
| 68 return nullptr; | |
| 69 } | |
| 70 | |
| 71 gpu::GpuMemoryBufferManager* | |
| 72 ChromeCompositorDependencies::GetGpuMemoryBufferManager() { | |
| 73 return context_provider_factory_->GetGpuMemoryBufferManager(); | |
| 74 } | |
| 75 | |
| 76 cc::SurfaceManager* ChromeCompositorDependencies::GetSurfaceManager() { | |
| 77 return context_provider_factory_->GetSurfaceManager(); | |
| 78 } | |
| 79 | |
| 80 uint32_t ChromeCompositorDependencies::AllocateSurfaceClientId() { | |
| 81 return context_provider_factory_->AllocateSurfaceClientId(); | |
| 82 } | |
| 83 | |
| 84 void ChromeCompositorDependencies::GetContextProviders( | |
| 85 const ContextProviderCallback& callback) { | |
| 86 bool worker_context_is_valid = false; | |
| 87 if (shared_main_thread_worker_context_) { | |
| 88 // Note: If context is lost, delete reference after releasing the lock. | |
| 89 cc::ContextProvider::ScopedContextLock lock( | |
| 90 shared_main_thread_worker_context_.get()); | |
| 91 if (shared_main_thread_worker_context_->ContextGL() | |
| 92 ->GetGraphicsResetStatusKHR() == GL_NO_ERROR) | |
| 93 worker_context_is_valid = true; | |
| 94 } | |
| 95 if (!worker_context_is_valid) | |
| 96 shared_main_thread_worker_context_ = nullptr; | |
|
David Trainor- moved to gerrit
2016/08/31 00:28:58
What happens to any outstanding requests if this d
Khushal
2016/08/31 21:22:50
Good call. I think the compositor expects the work
| |
| 97 | |
| 98 // Request a compositor context if the worker context is still valid. | |
| 99 if (shared_main_thread_worker_context_) { | |
| 100 HandleCompositorContextRequest(callback); | |
| 101 return; | |
| 102 } | |
| 103 | |
| 104 // Add the request to the list of pending requests first, if the result | |
| 105 // comes back synchronously, the callback should get triggered. | |
| 106 pending_requests_.push_back(callback); | |
| 107 | |
| 108 // If the request for a worker context is already pending, don't make | |
| 109 // another one. We'll handle all the pending requests together once the | |
| 110 // worker context is available. | |
| 111 if (worker_context_request_pending_) | |
| 112 return; | |
| 113 | |
| 114 worker_context_request_pending_ = true; | |
| 115 context_provider_factory_->CreateOffscreenContextProvider( | |
| 116 ui::ContextProviderFactory::ContextType::BLIMP_RENDER_WORKER_CONTEXT, | |
| 117 gpu::SharedMemoryLimits(), GetOffscreenContextCreationAttributes(), | |
| 118 true /* support_locking */, false /* automatic_flushes */, nullptr, | |
| 119 base::Bind(&ChromeCompositorDependencies::OnWorkerContextCreated, | |
| 120 weak_factory_.GetWeakPtr())); | |
| 121 } | |
| 122 | |
| 123 void ChromeCompositorDependencies::OnWorkerContextCreated( | |
| 124 const scoped_refptr<cc::ContextProvider>& worker_context) { | |
| 125 DCHECK(worker_context_request_pending_); | |
| 126 DCHECK(!shared_main_thread_worker_context_); | |
| 127 | |
| 128 worker_context_request_pending_ = false; | |
| 129 if (worker_context->BindToCurrentThread()) { | |
| 130 shared_main_thread_worker_context_ = worker_context; | |
| 131 } | |
|
David Trainor- moved to gerrit
2016/08/31 00:28:58
What if this returns false?
Khushal
2016/08/31 21:22:50
If the bind fails, then we just report the failure
| |
| 132 | |
| 133 // Copy the requests first since we can get more requests as we run these | |
| 134 // callbacks. | |
| 135 std::list<ContextProviderCallback> context_requests = pending_requests_; | |
| 136 pending_requests_.clear(); | |
| 137 | |
| 138 for (ContextProviderCallback& context_request : context_requests) { | |
| 139 HandleCompositorContextRequest(context_request); | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 void ChromeCompositorDependencies::HandleCompositorContextRequest( | |
| 144 const ContextProviderCallback& callback) { | |
| 145 // Respond with null contexts if the worker context could not be created. | |
| 146 if (!shared_main_thread_worker_context_) { | |
| 147 callback.Run(ContextProviders()); | |
| 148 return; | |
| 149 } | |
| 150 | |
| 151 ui::ContextProviderFactory::ContextProviderCallback result_callback = | |
| 152 base::Bind(&OnCompositorContextCreated, callback, | |
| 153 shared_main_thread_worker_context_); | |
| 154 | |
| 155 // The compositor context shares resources with the worker context unless | |
| 156 // the worker is async. | |
| 157 cc::ContextProvider* shared_context = | |
| 158 IsAsyncWorkerContextEnabled() ? nullptr | |
| 159 : shared_main_thread_worker_context_.get(); | |
| 160 | |
| 161 context_provider_factory_->CreateOffscreenContextProvider( | |
| 162 ui::ContextProviderFactory::ContextType::BLIMP_RENDER_COMPOSITOR_CONTEXT, | |
| 163 gpu::SharedMemoryLimits::ForMailboxContext(), | |
| 164 GetOffscreenContextCreationAttributes(), false /* support_locking */, | |
| 165 false /* automatic_flushes */, shared_context, result_callback); | |
| 166 } | |
| OLD | NEW |