blob: e84b19e707a0c9f9cbf2bcccdba72bf74f74d3c4 [file] [log] [blame]
// 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