blob: 2f73deab350374d3a95021999bf71548a8917194 [file] [log] [blame]
// Copyright 2020 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/command_buffer/service/shared_image/pbuffer_image_backing.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "components/viz/common/resources/resource_sizes.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/shared_image/shared_image_format_utils.h"
#include "gpu/command_buffer/service/skia_utils.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkPromiseImageTexture.h"
#include "third_party/skia/include/gpu/GrContextThreadSafeProxy.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_implementation.h"
namespace gpu {
PbufferImageBacking::PbufferImageBacking(
base::OnceClosure on_destruction_closure,
const Mailbox& mailbox,
viz::SharedImageFormat format,
const gfx::Size& size,
const gfx::ColorSpace& color_space,
GrSurfaceOrigin surface_origin,
SkAlphaType alpha_type,
uint32_t usage,
scoped_refptr<gles2::TexturePassthrough> passthrough_texture)
: ClearTrackingSharedImageBacking(mailbox,
format,
size,
color_space,
surface_origin,
alpha_type,
usage,
format.EstimatedSizeInBytes(size),
false /* is_thread_safe */),
on_destruction_closure_runner_(std::move(on_destruction_closure)),
passthrough_texture_(std::move(passthrough_texture)) {
DCHECK(!!passthrough_texture_);
}
PbufferImageBacking::~PbufferImageBacking() {
// If the cached promise texture is referencing the GL texture, then it needs
// to be deleted, too.
if (cached_promise_texture_) {
if (cached_promise_texture_->backendTexture().backend() ==
GrBackendApi::kOpenGL) {
cached_promise_texture_.reset();
}
}
if (!have_context())
passthrough_texture_->MarkContextLost();
passthrough_texture_.reset();
}
scoped_refptr<gfx::NativePixmap> PbufferImageBacking::GetNativePixmap() {
return nullptr;
}
SharedImageBackingType PbufferImageBacking::GetType() const {
return SharedImageBackingType::kGLImage;
}
std::unique_ptr<GLTextureImageRepresentation>
PbufferImageBacking::ProduceGLTexture(SharedImageManager* manager,
MemoryTypeTracker* tracker) {
NOTREACHED();
return nullptr;
}
std::unique_ptr<GLTexturePassthroughImageRepresentation>
PbufferImageBacking::ProduceGLTexturePassthrough(SharedImageManager* manager,
MemoryTypeTracker* tracker) {
DCHECK(passthrough_texture_);
return std::make_unique<GLTexturePassthroughGLCommonRepresentation>(
manager, this, this, tracker, passthrough_texture_);
}
std::unique_ptr<OverlayImageRepresentation> PbufferImageBacking::ProduceOverlay(
SharedImageManager* manager,
MemoryTypeTracker* tracker) {
// PbufferPictureBuffer does not support overlays (
// PbufferPictureBuffer::AllowOverlay() returns false), and so this method
// should never be invoked.
NOTREACHED();
return nullptr;
}
std::unique_ptr<DawnImageRepresentation> PbufferImageBacking::ProduceDawn(
SharedImageManager* manager,
MemoryTypeTracker* tracker,
WGPUDevice device,
WGPUBackendType backend_type,
std::vector<WGPUTextureFormat> view_formats) {
if (!factory()) {
DLOG(ERROR) << "No SharedImageFactory to create a dawn representation.";
return nullptr;
}
return GLTextureImageBackingHelper::ProduceDawnCommon(
factory(), manager, tracker, device, backend_type,
std::move(view_formats), this, true);
}
std::unique_ptr<SkiaImageRepresentation> PbufferImageBacking::ProduceSkia(
SharedImageManager* manager,
MemoryTypeTracker* tracker,
scoped_refptr<SharedContextState> context_state) {
GLTextureImageRepresentationClient* gl_client = nullptr;
if (context_state->GrContextIsGL()) {
gl_client = this;
}
if (!cached_promise_texture_) {
bool angle_rgbx_internal_format = context_state->feature_info()
->feature_flags()
.angle_rgbx_internal_format;
GLenum gl_texture_storage_format = TextureStorageFormat(
format(), angle_rgbx_internal_format, /*plane_index=*/0);
GrBackendTexture backend_texture;
GetGrBackendTexture(
context_state->feature_info(), GL_TEXTURE_2D, size(),
passthrough_texture_->service_id(), gl_texture_storage_format,
context_state->gr_context()->threadSafeProxy(), &backend_texture);
cached_promise_texture_ = SkPromiseImageTexture::Make(backend_texture);
}
return std::make_unique<SkiaGLCommonRepresentation>(
manager, this, gl_client, std::move(context_state),
cached_promise_texture_, tracker);
}
bool PbufferImageBacking::GLTextureImageRepresentationBeginAccess(
bool readonly) {
passthrough_texture_->clear_bind_pending();
return true;
}
void PbufferImageBacking::GLTextureImageRepresentationEndAccess(bool readonly) {
}
void PbufferImageBacking::GLTextureImageRepresentationRelease(
bool has_context) {
// No action needed: This class retains the passed-in texture for its
// lifetime, and releases it in its destructor.
}
} // namespace gpu