| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h" | 5 #include "chrome/browser/android/vr_shell/mailbox_to_surface_bridge.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/sys_info.h" | 11 #include "base/sys_info.h" |
| 12 #include "base/threading/sequenced_task_runner_handle.h" |
| 12 #include "cc/output/context_provider.h" | 13 #include "cc/output/context_provider.h" |
| 13 #include "content/public/browser/android/compositor.h" | 14 #include "content/public/browser/android/compositor.h" |
| 15 #include "content/public/browser/browser_thread.h" |
| 14 #include "gpu/GLES2/gl2extchromium.h" | 16 #include "gpu/GLES2/gl2extchromium.h" |
| 15 #include "gpu/command_buffer/client/gles2_interface.h" | 17 #include "gpu/command_buffer/client/gles2_interface.h" |
| 16 #include "gpu/command_buffer/common/mailbox.h" | 18 #include "gpu/command_buffer/common/mailbox.h" |
| 17 #include "gpu/command_buffer/common/mailbox_holder.h" | 19 #include "gpu/command_buffer/common/mailbox_holder.h" |
| 18 #include "gpu/command_buffer/common/sync_token.h" | 20 #include "gpu/command_buffer/common/sync_token.h" |
| 19 #include "gpu/ipc/client/gpu_channel_host.h" | 21 #include "gpu/ipc/client/gpu_channel_host.h" |
| 20 #include "gpu/ipc/common/gpu_surface_tracker.h" | 22 #include "gpu/ipc/common/gpu_surface_tracker.h" |
| 21 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" | 23 #include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" |
| 22 #include "ui/gl/android/surface_texture.h" | 24 #include "ui/gl/android/surface_texture.h" |
| 23 | 25 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 MailboxToSurfaceBridge::~MailboxToSurfaceBridge() { | 143 MailboxToSurfaceBridge::~MailboxToSurfaceBridge() { |
| 142 if (surface_handle_) { | 144 if (surface_handle_) { |
| 143 // Unregister from the surface tracker to avoid a resource leak. | 145 // Unregister from the surface tracker to avoid a resource leak. |
| 144 gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get(); | 146 gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get(); |
| 145 tracker->RemoveSurface(surface_handle_); | 147 tracker->RemoveSurface(surface_handle_); |
| 146 } | 148 } |
| 147 DestroyContext(); | 149 DestroyContext(); |
| 148 } | 150 } |
| 149 | 151 |
| 150 void MailboxToSurfaceBridge::OnContextAvailable( | 152 void MailboxToSurfaceBridge::OnContextAvailable( |
| 153 std::unique_ptr<gl::ScopedJavaSurface> surface, |
| 151 scoped_refptr<cc::ContextProvider> provider) { | 154 scoped_refptr<cc::ContextProvider> provider) { |
| 152 // Must save a reference to the ContextProvider to keep it alive, | 155 // Must save a reference to the ContextProvider to keep it alive, |
| 153 // otherwise the GL context created from it becomes invalid. | 156 // otherwise the GL context created from it becomes invalid. |
| 154 context_provider_ = std::move(provider); | 157 context_provider_ = std::move(provider); |
| 155 | 158 |
| 156 if (!context_provider_->BindToCurrentThread()) { | 159 if (!context_provider_->BindToCurrentThread()) { |
| 157 DLOG(ERROR) << "Failed to init ContextProvider"; | 160 DLOG(ERROR) << "Failed to init ContextProvider"; |
| 158 return; | 161 return; |
| 159 } | 162 } |
| 160 | 163 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 173 gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get(); | 176 gpu::GpuSurfaceTracker* tracker = gpu::GpuSurfaceTracker::Get(); |
| 174 ANativeWindow_acquire(window); | 177 ANativeWindow_acquire(window); |
| 175 // Skip ANativeWindow_setBuffersGeometry, the default size appears to work. | 178 // Skip ANativeWindow_setBuffersGeometry, the default size appears to work. |
| 176 auto surface = base::MakeUnique<gl::ScopedJavaSurface>(surface_texture); | 179 auto surface = base::MakeUnique<gl::ScopedJavaSurface>(surface_texture); |
| 177 surface_handle_ = | 180 surface_handle_ = |
| 178 tracker->AddSurfaceForNativeWidget(gpu::GpuSurfaceTracker::SurfaceRecord( | 181 tracker->AddSurfaceForNativeWidget(gpu::GpuSurfaceTracker::SurfaceRecord( |
| 179 window, surface->j_surface().obj())); | 182 window, surface->j_surface().obj())); |
| 180 // Unregistering happens in the destructor. | 183 // Unregistering happens in the destructor. |
| 181 ANativeWindow_release(window); | 184 ANativeWindow_release(window); |
| 182 | 185 |
| 183 // Our attributes must be compatible with the shared offscreen | 186 // The callback to run in this thread. It is necessary to keep |surface| alive |
| 184 // surface used by virtualized contexts, otherwise mailbox | 187 // until the context becomes available. So pass it on to the callback, so that |
| 185 // synchronization doesn't work properly - it assumes a shared | 188 // it stays alive, and is destroyed on the same thread once done. |
| 186 // underlying GL context. See GetCompositorContextAttributes | 189 auto callback = |
| 187 // in content/browser/renderer_host/compositor_impl_android.cc | 190 base::Bind(&MailboxToSurfaceBridge::OnContextAvailable, |
| 188 // and crbug.com/699330. | 191 weak_ptr_factory_.GetWeakPtr(), base::Passed(&surface)); |
| 192 // The callback that runs in the UI thread, and triggers |callback| to be run |
| 193 // in this thread. |
| 194 auto relay_callback = base::Bind( |
| 195 [](scoped_refptr<base::SequencedTaskRunner> runner, |
| 196 const content::Compositor::ContextProviderCallback& callback, |
| 197 scoped_refptr<cc::ContextProvider> provider) { |
| 198 runner->PostTask(FROM_HERE, base::Bind(callback, std::move(provider))); |
| 189 | 199 |
| 190 gpu::gles2::ContextCreationAttribHelper attributes; | 200 }, |
| 191 attributes.alpha_size = -1; | 201 base::SequencedTaskRunnerHandle::Get(), std::move(callback)); |
| 192 attributes.red_size = 8; | 202 content::BrowserThread::PostTask( |
| 193 attributes.green_size = 8; | 203 content::BrowserThread::UI, FROM_HERE, |
| 194 attributes.blue_size = 8; | 204 base::BindOnce( |
| 195 attributes.stencil_size = 0; | 205 [](int surface_handle, |
| 196 attributes.depth_size = 0; | 206 const content::Compositor::ContextProviderCallback& callback) { |
| 197 attributes.samples = 0; | 207 // Our attributes must be compatible with the shared |
| 198 attributes.sample_buffers = 0; | 208 // offscreen surface used by virtualized contexts, |
| 199 attributes.bind_generates_resource = false; | 209 // otherwise mailbox synchronization doesn't work |
| 200 if (base::SysInfo::IsLowEndDevice()) { | 210 // properly - it assumes a shared underlying GL context. |
| 201 attributes.alpha_size = 0; | 211 // See GetCompositorContextAttributes in |
| 202 attributes.red_size = 5; | 212 // content/browser/renderer_host/compositor_impl_android.cc |
| 203 attributes.green_size = 6; | 213 // and crbug.com/699330. |
| 204 attributes.blue_size = 5; | 214 gpu::gles2::ContextCreationAttribHelper attributes; |
| 205 } | 215 attributes.alpha_size = -1; |
| 206 | 216 attributes.red_size = 8; |
| 207 content::Compositor::CreateContextProvider( | 217 attributes.green_size = 8; |
| 208 surface_handle_, attributes, gpu::SharedMemoryLimits::ForMailboxContext(), | 218 attributes.blue_size = 8; |
| 209 base::Bind(&MailboxToSurfaceBridge::OnContextAvailable, | 219 attributes.stencil_size = 0; |
| 210 weak_ptr_factory_.GetWeakPtr())); | 220 attributes.depth_size = 0; |
| 221 attributes.samples = 0; |
| 222 attributes.sample_buffers = 0; |
| 223 attributes.bind_generates_resource = false; |
| 224 if (base::SysInfo::IsLowEndDevice()) { |
| 225 attributes.alpha_size = 0; |
| 226 attributes.red_size = 5; |
| 227 attributes.green_size = 6; |
| 228 attributes.blue_size = 5; |
| 229 } |
| 230 content::Compositor::CreateContextProvider( |
| 231 surface_handle, attributes, |
| 232 gpu::SharedMemoryLimits::ForMailboxContext(), callback); |
| 233 }, |
| 234 surface_handle_, relay_callback)); |
| 211 } | 235 } |
| 212 | 236 |
| 213 void MailboxToSurfaceBridge::ResizeSurface(int width, int height) { | 237 void MailboxToSurfaceBridge::ResizeSurface(int width, int height) { |
| 214 if (!gl_) { | 238 if (!gl_) { |
| 215 // We're not initialized yet, save the requested size for later. | 239 // We're not initialized yet, save the requested size for later. |
| 216 needs_resize_ = true; | 240 needs_resize_ = true; |
| 217 resize_width_ = width; | 241 resize_width_ = width; |
| 218 resize_height_ = height; | 242 resize_height_ = height; |
| 219 return; | 243 return; |
| 220 } | 244 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 // GL_NEAREST. | 362 // GL_NEAREST. |
| 339 gl_->BindTexture(GL_TEXTURE_2D, texture_handle); | 363 gl_->BindTexture(GL_TEXTURE_2D, texture_handle); |
| 340 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 364 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 341 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 365 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 342 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 366 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 343 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 367 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 344 gl_->DrawArrays(GL_TRIANGLE_FAN, 0, 4); | 368 gl_->DrawArrays(GL_TRIANGLE_FAN, 0, 4); |
| 345 } | 369 } |
| 346 | 370 |
| 347 } // namespace vr_shell | 371 } // namespace vr_shell |
| OLD | NEW |