Skip to content

Commit

Permalink
Reland gpu: Add disk caching for skia generated shaders in OOP-R.
Browse files Browse the repository at this point in the history
This reverts commit f9395d7.

Use the GrContextOptions::PersistentCache API provided by skia to
persist shaders generated internally by skia for OOP raster to disk.
This requires using a special client id to namespace these shaders,
similar to the one used by the InProcessCommandBuffer for viz.

While the shaders for different sources are stored seperately on disk,
they are finally merged into a single memory cache in the GPU process. In
order to maintain a seperate cache for skia generated shaders, this also
plumbs the client id for a loaded shader to the GPU process.

TBR=tsepez@chromium.org

Bug: 854416,840559, 865138
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I65544ccaff96c3154a822dbc2500468fbcac8a0b
Reviewed-on: https://chromium-review.googlesource.com/1142829
Commit-Queue: Khushal <khushalsagar@chromium.org>
Reviewed-by: Antoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576742}
  • Loading branch information
khushalsagar authored and Commit Bot committed Jul 20, 2018
1 parent 8a9a50c commit c2667e3
Show file tree
Hide file tree
Showing 30 changed files with 557 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class TestGpuService : public mojom::GpuService {
void EstablishGpuChannel(int32_t client_id,
uint64_t client_tracing_id,
bool is_gpu_host,
bool cache_shaders_on_disk,
EstablishGpuChannelCallback callback) override {}

void CloseChannel(int32_t client_id) override {}
Expand Down Expand Up @@ -111,7 +112,9 @@ class TestGpuService : public mojom::GpuService {

void RequestHDRStatus(RequestHDRStatusCallback callback) override {}

void LoadedShader(const std::string& key, const std::string& data) override {}
void LoadedShader(int32_t client_id,
const std::string& key,
const std::string& data) override {}

void WakeUpGpu() override {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h"

#include "base/bind.h"
#include "gpu/ipc/common/gpu_client_ids.h"
#include "gpu/ipc/common/gpu_memory_buffer_impl.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
#include "gpu/ipc/in_process_command_buffer.h"
Expand All @@ -16,7 +17,7 @@ namespace viz {
InProcessGpuMemoryBufferManager::InProcessGpuMemoryBufferManager(
gpu::GpuChannelManager* channel_manager)
: gpu_memory_buffer_support_(new gpu::GpuMemoryBufferSupport()),
client_id_(gpu::InProcessCommandBuffer::kGpuClientId),
client_id_(gpu::kInProcessCommandBufferClientId),
channel_manager_(channel_manager),
weak_factory_(this) {
weak_ptr_ = weak_factory_.GetWeakPtr();
Expand Down
23 changes: 14 additions & 9 deletions components/viz/service/gl/gpu_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "gpu/config/gpu_info_collector.h"
#include "gpu/config/gpu_switches.h"
#include "gpu/config/gpu_util.h"
#include "gpu/ipc/common/gpu_client_ids.h"
#include "gpu/ipc/common/gpu_memory_buffer_support.h"
#include "gpu/ipc/common/memory_stats.h"
#include "gpu/ipc/in_process_command_buffer.h"
Expand Down Expand Up @@ -702,8 +703,9 @@ void GpuServiceImpl::SetActiveURL(const GURL& url) {
void GpuServiceImpl::EstablishGpuChannel(int32_t client_id,
uint64_t client_tracing_id,
bool is_gpu_host,
bool cache_shaders_on_disk,
EstablishGpuChannelCallback callback) {
if (oopd_enabled_ && client_id == gpu::InProcessCommandBuffer::kGpuClientId) {
if (gpu::IsReservedClientId(client_id)) {
std::move(callback).Run(mojo::ScopedMessagePipeHandle());
return;
}
Expand All @@ -717,14 +719,15 @@ void GpuServiceImpl::EstablishGpuChannel(int32_t client_id,
},
io_runner_, std::move(callback));
main_runner_->PostTask(
FROM_HERE, base::BindOnce(&GpuServiceImpl::EstablishGpuChannel,
weak_ptr_, client_id, client_tracing_id,
is_gpu_host, std::move(wrap_callback)));
FROM_HERE,
base::BindOnce(&GpuServiceImpl::EstablishGpuChannel, weak_ptr_,
client_id, client_tracing_id, is_gpu_host,
cache_shaders_on_disk, std::move(wrap_callback)));
return;
}

gpu::GpuChannel* gpu_channel = gpu_channel_manager_->EstablishChannel(
client_id, client_tracing_id, is_gpu_host);
client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk);

mojo::MessagePipe pipe;
gpu_channel->Init(std::make_unique<gpu::SyncChannelFilteredSender>(
Expand All @@ -744,14 +747,16 @@ void GpuServiceImpl::CloseChannel(int32_t client_id) {
gpu_channel_manager_->RemoveChannel(client_id);
}

void GpuServiceImpl::LoadedShader(const std::string& key,
void GpuServiceImpl::LoadedShader(int32_t client_id,
const std::string& key,
const std::string& data) {
if (io_runner_->BelongsToCurrentThread()) {
main_runner_->PostTask(FROM_HERE, base::Bind(&GpuServiceImpl::LoadedShader,
weak_ptr_, key, data));
main_runner_->PostTask(FROM_HERE,
base::Bind(&GpuServiceImpl::LoadedShader, weak_ptr_,
client_id, key, data));
return;
}
gpu_channel_manager_->PopulateShaderCache(key, data);
gpu_channel_manager_->PopulateShaderCache(client_id, key, data);
}

void GpuServiceImpl::WakeUpGpu() {
Expand Down
5 changes: 4 additions & 1 deletion components/viz/service/gl/gpu_service_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
void EstablishGpuChannel(int32_t client_id,
uint64_t client_tracing_id,
bool is_gpu_host,
bool cache_shaders_on_disk,
EstablishGpuChannelCallback callback) override;
void CloseChannel(int32_t client_id) override;
#if defined(OS_CHROMEOS)
Expand Down Expand Up @@ -217,7 +218,9 @@ class VIZ_SERVICE_EXPORT GpuServiceImpl : public gpu::GpuChannelManagerDelegate,
void GetGpuSupportedRuntimeVersion(
GetGpuSupportedRuntimeVersionCallback callback) override;
void RequestHDRStatus(RequestHDRStatusCallback callback) override;
void LoadedShader(const std::string& key, const std::string& data) override;
void LoadedShader(int32_t client_id,
const std::string& key,
const std::string& data) override;
void WakeUpGpu() override;
void GpuSwitched() override;
void DestroyAllChannels() override;
Expand Down
3 changes: 2 additions & 1 deletion content/browser/gpu/browser_gpu_channel_host_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/ipc/common/gpu_client_ids.h"
#include "gpu/ipc/in_process_command_buffer.h"
#include "services/resource_coordinator/public/mojom/memory_instrumentation/constants.mojom.h"
#include "services/service_manager/runner/common/client_util.h"
Expand Down Expand Up @@ -386,7 +387,7 @@ void BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO(
GetShaderCacheFactorySingleton()->SetCacheInfo(gpu_client_id, cache_dir);
if (base::FeatureList::IsEnabled(features::kVizDisplayCompositor)) {
GetShaderCacheFactorySingleton()->SetCacheInfo(
gpu::InProcessCommandBuffer::kGpuClientId, cache_dir);
gpu::kInProcessCommandBufferClientId, cache_dir);
}
}

Expand Down
16 changes: 10 additions & 6 deletions content/browser/gpu/gpu_process_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "gpu/config/gpu_driver_bug_list.h"
#include "gpu/config/gpu_driver_bug_workaround_type.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/ipc/common/gpu_client_ids.h"
#include "gpu/ipc/host/shader_disk_cache.h"
#include "gpu/ipc/in_process_command_buffer.h"
#include "media/base/media_switches.h"
Expand Down Expand Up @@ -996,7 +997,7 @@ void GpuProcessHost::EstablishGpuChannel(

bool oopd_enabled =
base::FeatureList::IsEnabled(features::kVizDisplayCompositor);
if (oopd_enabled && client_id == gpu::InProcessCommandBuffer::kGpuClientId) {
if (oopd_enabled && client_id == gpu::kInProcessCommandBufferClientId) {
// The display-compositor in the gpu process uses this special client id.
callback.Run(mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
gpu::GpuFeatureInfo(),
Expand All @@ -1009,16 +1010,17 @@ void GpuProcessHost::EstablishGpuChannel(
bool is_gpu_host = preempts;

channel_requests_.push(callback);
const bool cache_shaders_on_disk = true;
gpu_service_ptr_->EstablishGpuChannel(
client_id, client_tracing_id, is_gpu_host,
client_id, client_tracing_id, is_gpu_host, cache_shaders_on_disk,
base::BindOnce(&GpuProcessHost::OnChannelEstablished,
weak_ptr_factory_.GetWeakPtr(), client_id, callback));

if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableGpuShaderDiskCache)) {
CreateChannelCache(client_id);
if (oopd_enabled)
CreateChannelCache(gpu::InProcessCommandBuffer::kGpuClientId);
CreateChannelCache(gpu::kInProcessCommandBufferClientId);
}
}

Expand Down Expand Up @@ -1588,15 +1590,16 @@ std::string GpuProcessHost::GetShaderPrefixKey() {
return shader_prefix_key_;
}

void GpuProcessHost::LoadedShader(const std::string& key,
void GpuProcessHost::LoadedShader(int32_t client_id,
const std::string& key,
const std::string& data) {
std::string prefix = GetShaderPrefixKey();
bool prefix_ok = !key.compare(0, prefix.length(), prefix);
UMA_HISTOGRAM_BOOLEAN("GPU.ShaderLoadPrefixOK", prefix_ok);
if (prefix_ok) {
// Remove the prefix from the key before load.
std::string key_no_prefix = key.substr(prefix.length() + 1);
gpu_service_ptr_->LoadedShader(key_no_prefix, data);
gpu_service_ptr_->LoadedShader(client_id, key_no_prefix, data);
}
}

Expand All @@ -1614,7 +1617,8 @@ void GpuProcessHost::CreateChannelCache(int32_t client_id) {
return;

cache->set_shader_loaded_callback(base::Bind(&GpuProcessHost::LoadedShader,
weak_ptr_factory_.GetWeakPtr()));
weak_ptr_factory_.GetWeakPtr(),
client_id));

client_id_to_shader_cache_[client_id] = cache;
}
Expand Down
4 changes: 3 additions & 1 deletion content/browser/gpu/gpu_process_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ class GpuProcessHost : public BrowserChildProcessHostDelegate,
// Forcefully terminates the GPU process.
void ForceShutdown();

void LoadedShader(const std::string& key, const std::string& data);
void LoadedShader(int32_t client_id,
const std::string& key,
const std::string& data);

CONTENT_EXPORT viz::mojom::GpuService* gpu_service();

Expand Down
1 change: 1 addition & 0 deletions gpu/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ test("gpu_unittests") {
"command_buffer/service/gpu_service_test.h",
"command_buffer/service/gpu_tracer_unittest.cc",
"command_buffer/service/gr_cache_controller_unittest.cc",
"command_buffer/service/gr_shader_cache_unittest.cc",
"command_buffer/service/id_manager_unittest.cc",
"command_buffer/service/indexed_buffer_binding_host_unittest.cc",
"command_buffer/service/mailbox_manager_unittest.cc",
Expand Down
2 changes: 2 additions & 0 deletions gpu/command_buffer/service/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ target(link_target_type, "gles2_sources") {
"gpu_tracer.h",
"gr_cache_controller.cc",
"gr_cache_controller.h",
"gr_shader_cache.cc",
"gr_shader_cache.h",
"id_manager.cc",
"id_manager.h",
"indexed_buffer_binding_host.cc",
Expand Down
2 changes: 1 addition & 1 deletion gpu/command_buffer/service/gr_cache_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class GrCacheControllerTest : public testing::Test {
context_state_ = new raster::RasterDecoderContextState(
std::move(share_group), std::move(surface), std::move(context),
false /* use_virtualized_gl_contexts */);
context_state_->InitializeGrContext(workarounds);
context_state_->InitializeGrContext(workarounds, nullptr);

controller_ =
std::make_unique<GrCacheController>(context_state_.get(), task_runner_);
Expand Down
164 changes: 164 additions & 0 deletions gpu/command_buffer/service/gr_shader_cache.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright (c) 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gpu/command_buffer/service/gr_shader_cache.h"

#include "base/trace_event/trace_event.h"

namespace gpu {
namespace raster {
namespace {

std::string MakeString(const SkData* data) {
return std::string(static_cast<const char*>(data->data()), data->size());
}

sk_sp<SkData> MakeData(const std::string& str) {
return SkData::MakeWithCopy(str.c_str(), str.length());
}

} // namespace

GrShaderCache::GrShaderCache(size_t max_cache_size_bytes, Client* client)
: cache_size_limit_(max_cache_size_bytes),
store_(Store::NO_AUTO_EVICT),
client_(client) {}

GrShaderCache::~GrShaderCache() = default;

sk_sp<SkData> GrShaderCache::load(const SkData& key) {
TRACE_EVENT0("gpu", "GrShaderCache::load");
DCHECK_NE(current_client_id_, kInvalidClientId);

CacheKey cache_key(SkData::MakeWithoutCopy(key.data(), key.size()));
auto it = store_.Get(cache_key);
if (it == store_.end())
return nullptr;

WriteToDisk(it->first, &it->second);
return it->second.data;
}

void GrShaderCache::store(const SkData& key, const SkData& data) {
TRACE_EVENT0("gpu", "GrShaderCache::store");
DCHECK_NE(current_client_id_, kInvalidClientId);

if (data.size() > cache_size_limit_)
return;
EnforceLimits(data.size());

CacheKey cache_key(SkData::MakeWithCopy(key.data(), key.size()));
CacheData cache_data(SkData::MakeWithCopy(data.data(), data.size()));
auto it = store_.Put(std::move(cache_key), std::move(cache_data));
curr_size_bytes_ += it->second.data->size();

WriteToDisk(it->first, &it->second);
}

void GrShaderCache::PopulateCache(const std::string& key,
const std::string& data) {
if (data.length() > cache_size_limit_)
return;

EnforceLimits(data.size());

CacheKey cache_key(MakeData(key));
CacheData cache_data(MakeData(data));
auto it = store_.Put(std::move(cache_key), std::move(cache_data));
curr_size_bytes_ += it->second.data->size();

// This was loaded off the disk cache, no need to push this back for disk
// write.
it->second.pending_disk_write = false;
}

void GrShaderCache::CacheClientIdOnDisk(int32_t client_id) {
client_ids_to_cache_on_disk_.insert(client_id);
}

void GrShaderCache::PurgeMemory(
base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
size_t original_limit = cache_size_limit_;

switch (memory_pressure_level) {
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
// This function is only called with moderate or critical pressure.
NOTREACHED();
return;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
cache_size_limit_ = cache_size_limit_ / 4;
break;
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
cache_size_limit_ = 0;
break;
}

EnforceLimits(0u);
cache_size_limit_ = original_limit;
}

void GrShaderCache::WriteToDisk(const CacheKey& key, CacheData* data) {
DCHECK_NE(current_client_id_, kInvalidClientId);

if (!data->pending_disk_write)
return;

// Only cache the shader on disk if this client id is permitted.
if (client_ids_to_cache_on_disk_.count(current_client_id_) == 0)
return;

data->pending_disk_write = false;
client_->StoreShader(MakeString(key.data.get()),
MakeString(data->data.get()));
}

void GrShaderCache::EnforceLimits(size_t size_needed) {
DCHECK_LE(size_needed, cache_size_limit_);

while (size_needed + curr_size_bytes_ > cache_size_limit_) {
auto it = store_.rbegin();
DCHECK_GE(curr_size_bytes_, it->second.data->size());
curr_size_bytes_ -= it->second.data->size();
store_.Erase(it);
}
}

GrShaderCache::ScopedCacheUse::ScopedCacheUse(GrShaderCache* cache,
int32_t client_id)
: cache_(cache) {
cache_->current_client_id_ = client_id;
}

GrShaderCache::ScopedCacheUse::~ScopedCacheUse() {
cache_->current_client_id_ = kInvalidClientId;
}

GrShaderCache::CacheKey::CacheKey(sk_sp<SkData> data) : data(std::move(data)) {
hash = base::Hash(this->data->data(), this->data->size());
}
GrShaderCache::CacheKey::CacheKey(const CacheKey& other) = default;
GrShaderCache::CacheKey::CacheKey(CacheKey&& other) = default;
GrShaderCache::CacheKey& GrShaderCache::CacheKey::operator=(
const CacheKey& other) = default;
GrShaderCache::CacheKey& GrShaderCache::CacheKey::operator=(CacheKey&& other) =
default;
GrShaderCache::CacheKey::~CacheKey() = default;

bool GrShaderCache::CacheKey::operator==(const CacheKey& other) const {
return data->equals(other.data.get());
}

GrShaderCache::CacheData::CacheData(sk_sp<SkData> data)
: data(std::move(data)) {}
GrShaderCache::CacheData::CacheData(CacheData&& other) = default;
GrShaderCache::CacheData& GrShaderCache::CacheData::operator=(
CacheData&& other) = default;
GrShaderCache::CacheData::~CacheData() = default;

bool GrShaderCache::CacheData::operator==(const CacheData& other) const {
return data->equals(other.data.get());
}

} // namespace raster
} // namespace gpu
Loading

0 comments on commit c2667e3

Please sign in to comment.