blob: 55eefb671c86922dd74a196f51132203b4df5e13 [file] [log] [blame]
// Copyright 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/shared_image_factory.h"
#include <inttypes.h>
#include "base/strings/stringprintf.h"
#include "base/trace_event/memory_dump_manager.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/image_factory.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/service_utils.h"
#include "gpu/command_buffer/service/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image_backing_factory_gl_texture.h"
#include "gpu/command_buffer/service/shared_image_manager.h"
#include "gpu/command_buffer/service/shared_image_representation.h"
#include "gpu/command_buffer/service/wrapped_sk_image.h"
#include "gpu/config/gpu_preferences.h"
#include "ui/gl/trace_util.h"
namespace gpu {
// Overrides for flat_set lookups:
bool operator<(
const std::unique_ptr<SharedImageRepresentationFactoryRef>& lhs,
const std::unique_ptr<SharedImageRepresentationFactoryRef>& rhs) {
return lhs->mailbox() < rhs->mailbox();
}
bool operator<(
const Mailbox& lhs,
const std::unique_ptr<SharedImageRepresentationFactoryRef>& rhs) {
return lhs < rhs->mailbox();
}
bool operator<(const std::unique_ptr<SharedImageRepresentationFactoryRef>& lhs,
const Mailbox& rhs) {
return lhs->mailbox() < rhs;
}
SharedImageFactory::SharedImageFactory(
const GpuPreferences& gpu_preferences,
const GpuDriverBugWorkarounds& workarounds,
const GpuFeatureInfo& gpu_feature_info,
raster::RasterDecoderContextState* context_state,
MailboxManager* mailbox_manager,
SharedImageManager* shared_image_manager,
ImageFactory* image_factory,
MemoryTracker* memory_tracker)
: mailbox_manager_(mailbox_manager),
shared_image_manager_(shared_image_manager),
memory_tracker_(std::make_unique<MemoryTypeTracker>(memory_tracker)),
backing_factory_(
std::make_unique<SharedImageBackingFactoryGLTexture>(gpu_preferences,
workarounds,
gpu_feature_info,
image_factory)),
wrapped_sk_image_factory_(
gpu_preferences.enable_raster_to_sk_image
? std::make_unique<raster::WrappedSkImageFactory>(context_state)
: nullptr) {}
SharedImageFactory::~SharedImageFactory() {
DCHECK(shared_images_.empty());
}
bool SharedImageFactory::CreateSharedImage(const Mailbox& mailbox,
viz::ResourceFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage) {
std::unique_ptr<SharedImageBacking> backing;
bool using_wrapped_sk_image = wrapped_sk_image_factory_ &&
(usage & SHARED_IMAGE_USAGE_OOP_RASTERIZATION);
if (using_wrapped_sk_image) {
backing = wrapped_sk_image_factory_->CreateSharedImage(
mailbox, format, size, color_space, usage);
} else {
backing = backing_factory_->CreateSharedImage(mailbox, format, size,
color_space, usage);
}
return RegisterBacking(std::move(backing), !using_wrapped_sk_image);
}
bool SharedImageFactory::CreateSharedImage(const Mailbox& mailbox,
int client_id,
gfx::GpuMemoryBufferHandle handle,
gfx::BufferFormat format,
SurfaceHandle surface_handle,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
uint32_t usage) {
// TODO(piman): depending on handle.type, choose platform-specific backing
// factory, e.g. SharedImageBackingFactoryAHardwareBuffer.
std::unique_ptr<SharedImageBacking> backing =
backing_factory_->CreateSharedImage(mailbox, client_id, std::move(handle),
format, surface_handle, size,
color_space, usage);
return RegisterBacking(std::move(backing), true);
}
bool SharedImageFactory::UpdateSharedImage(const Mailbox& mailbox) {
auto it = shared_images_.find(mailbox);
if (it == shared_images_.end()) {
LOG(ERROR) << "UpdateSharedImage: Could not find shared image mailbox";
return false;
}
(*it)->Update();
return true;
}
bool SharedImageFactory::DestroySharedImage(const Mailbox& mailbox) {
auto it = shared_images_.find(mailbox);
if (it == shared_images_.end()) {
LOG(ERROR) << "DestroySharedImage: Could not find shared image mailbox";
return false;
}
shared_images_.erase(it);
return true;
}
void SharedImageFactory::DestroyAllSharedImages(bool have_context) {
if (!have_context) {
for (auto& shared_image : shared_images_)
shared_image->OnContextLost();
}
shared_images_.clear();
}
// TODO(ericrk): Move this entirely to SharedImageManager.
bool SharedImageFactory::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd,
int client_id,
uint64_t client_tracing_id) {
for (const auto& shared_image : shared_images_) {
shared_image_manager_->OnMemoryDump(shared_image->mailbox(), pmd, client_id,
client_tracing_id);
}
return true;
}
bool SharedImageFactory::RegisterBacking(
std::unique_ptr<SharedImageBacking> backing,
bool legacy_mailbox) {
if (!backing) {
LOG(ERROR) << "CreateSharedImage: could not create backing.";
return false;
}
Mailbox mailbox = backing->mailbox();
if (shared_image_manager_->IsSharedImage(mailbox)) {
LOG(ERROR) << "CreateSharedImage: mailbox is already associated with a "
"SharedImage";
backing->Destroy();
return false;
}
std::unique_ptr<SharedImageRepresentationFactoryRef> shared_image =
shared_image_manager_->Register(std::move(backing),
memory_tracker_.get());
// TODO(ericrk): Remove this once no legacy cases remain.
if (legacy_mailbox && !shared_image->ProduceLegacyMailbox(mailbox_manager_)) {
LOG(ERROR) << "CreateSharedImage: could not convert shared_image to legacy "
"mailbox.";
return false;
}
shared_images_.emplace(std::move(shared_image));
return true;
}
SharedImageRepresentationFactory::SharedImageRepresentationFactory(
SharedImageManager* manager,
MemoryTracker* tracker)
: manager_(manager),
tracker_(std::make_unique<MemoryTypeTracker>(tracker)) {}
SharedImageRepresentationFactory::~SharedImageRepresentationFactory() {
DCHECK_EQ(0u, tracker_->GetMemRepresented());
}
std::unique_ptr<SharedImageRepresentationGLTexture>
SharedImageRepresentationFactory::ProduceGLTexture(const Mailbox& mailbox) {
return manager_->ProduceGLTexture(mailbox, tracker_.get());
}
std::unique_ptr<SharedImageRepresentationGLTexturePassthrough>
SharedImageRepresentationFactory::ProduceGLTexturePassthrough(
const Mailbox& mailbox) {
return manager_->ProduceGLTexturePassthrough(mailbox, tracker_.get());
}
std::unique_ptr<SharedImageRepresentationSkia>
SharedImageRepresentationFactory::ProduceSkia(const Mailbox& mailbox) {
return manager_->ProduceSkia(mailbox, tracker_.get());
}
} // namespace gpu