910e62b5创建于 1月15日历史提交
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/ipc/raster_in_process_context.h"

#include <utility>

#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/logging.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/raster_cmd_helper.h"
#include "gpu/command_buffer/client/shared_memory_limits.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/ipc/common/surface_handle.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace gpu {

RasterInProcessContext::RasterInProcessContext() = default;

RasterInProcessContext::~RasterInProcessContext() {
  // Trigger any pending lost contexts. First do a full sync between client
  // and service threads. Then execute any pending tasks.
  if (raster_implementation_) {
    raster_implementation_->Finish();
    base::RunLoop().RunUntilIdle();
    raster_implementation_.reset();
  }
  transfer_buffer_.reset();
  helper_.reset();
  command_buffer_.reset();
}

ContextResult RasterInProcessContext::Initialize(
    CommandBufferTaskExecutor* task_executor,
    bool enable_gpu_rasterization,
    gpu::raster::GrShaderCache* gr_shader_cache,
    GpuProcessShmCount* use_shader_cache_shm_count) {
  constexpr bool lose_context_when_out_of_memory = false;
  auto attribs = mojom::ContextCreationAttribs::NewRaster(
      mojom::RasterCreationAttribs::New(
          /*enable_gpu_rasterization=*/enable_gpu_rasterization,
          /*lose_context_when_out_of_memory=*/lose_context_when_out_of_memory));

  command_buffer_ =
      std::make_unique<InProcessCommandBuffer>(task_executor, GURL());
  auto result = command_buffer_->Initialize(
      std::move(attribs), base::SingleThreadTaskRunner::GetCurrentDefault(),
      gr_shader_cache, use_shader_cache_shm_count);
  if (result != ContextResult::kSuccess) {
    DLOG(ERROR) << "Failed to initialize InProcessCommmandBuffer";
    return result;
  }

  const SharedMemoryLimits memory_limits;

  // Create the RasterCmdHelper, which writes the command buffer protocol.
  auto raster_helper =
      std::make_unique<raster::RasterCmdHelper>(command_buffer_.get());
  result = raster_helper->Initialize(memory_limits.command_buffer_size);
  if (result != ContextResult::kSuccess) {
    LOG(ERROR) << "Failed to initialize RasterCmdHelper";
    return result;
  }
  transfer_buffer_ = std::make_unique<TransferBuffer>(raster_helper.get());

  raster_implementation_ = std::make_unique<raster::RasterImplementation>(
      raster_helper.get(), transfer_buffer_.get(),
      /*lose_context_when_out_of_memory=*/lose_context_when_out_of_memory,
      command_buffer_.get());
  result = raster_implementation_->Initialize(memory_limits);
  raster_implementation_->SetLostContextCallback(base::BindOnce(
      []() { EXPECT_TRUE(false) << "Unexpected lost context."; }));
  helper_ = std::move(raster_helper);
  return result;
}

const Capabilities& RasterInProcessContext::GetCapabilities() const {
  return command_buffer_->GetCapabilities();
}

const GpuFeatureInfo& RasterInProcessContext::GetGpuFeatureInfo() const {
  return command_buffer_->GetGpuFeatureInfo();
}

raster::RasterImplementation* RasterInProcessContext::GetImplementation() {
  return raster_implementation_.get();
}

ContextSupport* RasterInProcessContext::GetContextSupport() {
  return raster_implementation_.get();
}

SharedImageInterface* RasterInProcessContext::GetSharedImageInterface() {
  return command_buffer_->GetSharedImageInterface();
}

ServiceTransferCache* RasterInProcessContext::GetTransferCacheForTest() const {
  return command_buffer_->GetTransferCacheForTest();
}

InProcessCommandBuffer* RasterInProcessContext::GetCommandBufferForTest()
    const {
  return command_buffer_.get();
}

int RasterInProcessContext::GetRasterDecoderIdForTest() const {
  return command_buffer_->GetRasterDecoderIdForTest();
}

// static
bool RasterInProcessContext::SupportedInTest() {
  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();
  GpuPreferences gpu_preferences = gles2::ParseGpuPreferences(command_line);
  return !gpu_preferences.use_passthrough_cmd_decoder;
}

}  // namespace gpu