|  | // Copyright 2013 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "components/viz/test/test_in_process_context_provider.h" | 
|  |  | 
|  | #include <stdint.h> | 
|  |  | 
|  | #include <memory> | 
|  | #include <utility> | 
|  |  | 
|  | #include "base/task/single_thread_task_runner.h" | 
|  | #include "base/types/optional_util.h" | 
|  | #include "components/viz/common/gpu/context_cache_controller.h" | 
|  | #include "components/viz/common/resources/shared_image_format_utils.h" | 
|  | #include "components/viz/service/gl/gpu_service_impl.h" | 
|  | #include "components/viz/test/test_gpu_service_holder.h" | 
|  | #include "gpu/command_buffer/client/gles2_implementation.h" | 
|  | #include "gpu/command_buffer/client/shared_memory_limits.h" | 
|  | #include "gpu/command_buffer/common/context_creation_attribs.h" | 
|  | #include "gpu/config/skia_limits.h" | 
|  | #include "gpu/ipc/gl_in_process_context.h" | 
|  | #include "gpu/ipc/raster_in_process_context.h" | 
|  |  | 
|  | namespace viz { | 
|  |  | 
|  | TestInProcessContextProvider::TestInProcessContextProvider( | 
|  | TestContextType type, | 
|  | bool support_locking, | 
|  | gpu::raster::GrShaderCache* gr_shader_cache, | 
|  | gpu::GpuProcessShmCount* use_shader_cache_shm_count) | 
|  | : type_(type), use_shader_cache_shm_count_(use_shader_cache_shm_count) { | 
|  | CHECK(main_thread_checker_.CalledOnValidThread()); | 
|  | context_thread_checker_.DetachFromThread(); | 
|  |  | 
|  | if (support_locking) { | 
|  | context_lock_.emplace(); | 
|  | } | 
|  | } | 
|  |  | 
|  | TestInProcessContextProvider::~TestInProcessContextProvider() { | 
|  | CHECK(main_thread_checker_.CalledOnValidThread() || | 
|  | context_thread_checker_.CalledOnValidThread()); | 
|  | } | 
|  |  | 
|  | void TestInProcessContextProvider::AddRef() const { | 
|  | base::RefCountedThreadSafe<TestInProcessContextProvider>::AddRef(); | 
|  | } | 
|  |  | 
|  | void TestInProcessContextProvider::Release() const { | 
|  | base::RefCountedThreadSafe<TestInProcessContextProvider>::Release(); | 
|  | } | 
|  |  | 
|  | gpu::ContextResult TestInProcessContextProvider::BindToCurrentSequence() { | 
|  | CHECK(context_thread_checker_.CalledOnValidThread()); | 
|  |  | 
|  | if (is_bound_) { | 
|  | return gpu::ContextResult::kSuccess; | 
|  | } | 
|  |  | 
|  | auto* holder = TestGpuServiceHolder::GetInstance(); | 
|  |  | 
|  | if (type_ == TestContextType::kGLES2) { | 
|  | gles2_context_ = std::make_unique<gpu::GLInProcessContext>(); | 
|  | auto result = gles2_context_->Initialize( | 
|  | TestGpuServiceHolder::GetInstance()->task_executor()); | 
|  | CHECK_EQ(result, gpu::ContextResult::kSuccess); | 
|  |  | 
|  | caps_ = gles2_context_->GetCapabilities(); | 
|  | } else { | 
|  | const bool is_gpu_raster = type_ == TestContextType::kGpuRaster; | 
|  |  | 
|  | raster_context_ = std::make_unique<gpu::RasterInProcessContext>(); | 
|  | auto result = raster_context_->Initialize( | 
|  | holder->task_executor(), /*enable_gpu_rasterization=*/is_gpu_raster, | 
|  | holder->gpu_service()->gr_shader_cache(), use_shader_cache_shm_count_); | 
|  | CHECK_EQ(result, gpu::ContextResult::kSuccess); | 
|  |  | 
|  | caps_ = raster_context_->GetCapabilities(); | 
|  | CHECK_EQ(caps_.gpu_rasterization, is_gpu_raster); | 
|  | } | 
|  |  | 
|  | cache_controller_ = std::make_unique<ContextCacheController>( | 
|  | ContextSupport(), base::SingleThreadTaskRunner::GetCurrentDefault()); | 
|  | cache_controller_->SetLock(GetLock()); | 
|  |  | 
|  | is_bound_ = true; | 
|  | return gpu::ContextResult::kSuccess; | 
|  | } | 
|  |  | 
|  | gpu::gles2::GLES2Interface* TestInProcessContextProvider::ContextGL() { | 
|  | CheckValidThreadOrLockAcquired(); | 
|  | CHECK(gles2_context_); | 
|  | return gles2_context_->GetImplementation(); | 
|  | } | 
|  |  | 
|  | gpu::raster::RasterInterface* TestInProcessContextProvider::RasterInterface() { | 
|  | CheckValidThreadOrLockAcquired(); | 
|  | CHECK(raster_context_); | 
|  | return raster_context_->GetImplementation(); | 
|  | } | 
|  |  | 
|  | gpu::ContextSupport* TestInProcessContextProvider::ContextSupport() { | 
|  | return gles2_context_ ? gles2_context_->GetImplementation() | 
|  | : raster_context_->GetContextSupport(); | 
|  | } | 
|  |  | 
|  | gpu::SharedImageInterface* | 
|  | TestInProcessContextProvider::SharedImageInterface() { | 
|  | return gles2_context_ ? gles2_context_->GetSharedImageInterface() | 
|  | : raster_context_->GetSharedImageInterface(); | 
|  | } | 
|  |  | 
|  | ContextCacheController* TestInProcessContextProvider::CacheController() { | 
|  | CheckValidThreadOrLockAcquired(); | 
|  | return cache_controller_.get(); | 
|  | } | 
|  |  | 
|  | base::Lock* TestInProcessContextProvider::GetLock() { | 
|  | return base::OptionalToPtr(context_lock_); | 
|  | } | 
|  |  | 
|  | const gpu::Capabilities& TestInProcessContextProvider::ContextCapabilities() | 
|  | const { | 
|  | CheckValidThreadOrLockAcquired(); | 
|  | return caps_; | 
|  | } | 
|  |  | 
|  | const gpu::GpuFeatureInfo& TestInProcessContextProvider::GetGpuFeatureInfo() | 
|  | const { | 
|  | CheckValidThreadOrLockAcquired(); | 
|  | return gles2_context_ ? gles2_context_->GetGpuFeatureInfo() | 
|  | : raster_context_->GetGpuFeatureInfo(); | 
|  | } | 
|  |  | 
|  | void TestInProcessContextProvider::AddObserver(ContextLostObserver* obs) { | 
|  | observers_.AddObserver(obs); | 
|  | } | 
|  |  | 
|  | void TestInProcessContextProvider::RemoveObserver(ContextLostObserver* obs) { | 
|  | observers_.RemoveObserver(obs); | 
|  | } | 
|  |  | 
|  | void TestInProcessContextProvider::SendOnContextLost() { | 
|  | for (auto& observer : observers_) { | 
|  | observer.OnContextLost(); | 
|  | } | 
|  | } | 
|  |  | 
|  | void TestInProcessContextProvider::ExecuteOnGpuThread(base::OnceClosure task) { | 
|  | CHECK(raster_context_); | 
|  | raster_context_->GetCommandBufferForTest() | 
|  | ->service_for_testing() | 
|  | ->ScheduleOutOfOrderTask(std::move(task)); | 
|  | } | 
|  |  | 
|  | void TestInProcessContextProvider::CheckValidThreadOrLockAcquired() const { | 
|  | #if DCHECK_IS_ON() | 
|  | if (context_lock_) { | 
|  | context_lock_->AssertAcquired(); | 
|  | } else { | 
|  | DCHECK(context_thread_checker_.CalledOnValidThread()); | 
|  | } | 
|  | #endif | 
|  | } | 
|  |  | 
|  | GpuServiceImpl* TestInProcessContextProvider::GpuService() { | 
|  | return TestGpuServiceHolder::GetInstance()->gpu_service(); | 
|  | } | 
|  |  | 
|  | }  // namespace viz |