blob: d23d5358e2f81b16192c5e6395a2667d3ff4f3e0 [file] [log] [blame]
// Copyright 2019 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_representation_skia_gl.h"
#include "base/memory/ptr_util.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/command_buffer/service/shared_context_state.h"
#include "gpu/command_buffer/service/skia_utils.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "third_party/skia/include/core/SkPromiseImageTexture.h"
#include "third_party/skia/include/gpu/GrBackendSurface.h"
#include "ui/gl/gl_bindings.h"
namespace gpu {
std::ostream& operator<<(std::ostream& os, RepresentationAccessMode mode) {
switch (mode) {
case RepresentationAccessMode::kNone:
os << "kNone";
break;
case RepresentationAccessMode::kRead:
os << "kRead";
break;
case RepresentationAccessMode::kWrite:
os << "kWrite";
break;
}
return os;
}
// static method.
std::unique_ptr<SharedImageRepresentationSkiaGL>
SharedImageRepresentationSkiaGL::Create(
std::unique_ptr<SharedImageRepresentationGLTextureBase> gl_representation,
scoped_refptr<SharedContextState> context_state,
SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker) {
GrBackendTexture backend_texture;
if (!GetGrBackendTexture(context_state->feature_info(),
gl_representation->GetTextureBase()->target(),
backing->size(),
gl_representation->GetTextureBase()->service_id(),
backing->format(), &backend_texture)) {
return nullptr;
}
auto promise_texture = SkPromiseImageTexture::Make(backend_texture);
if (!promise_texture)
return nullptr;
return base::WrapUnique(new SharedImageRepresentationSkiaGL(
std::move(gl_representation), std::move(promise_texture),
std::move(context_state), manager, backing, tracker));
}
SharedImageRepresentationSkiaGL::SharedImageRepresentationSkiaGL(
std::unique_ptr<SharedImageRepresentationGLTextureBase> gl_representation,
sk_sp<SkPromiseImageTexture> promise_texture,
scoped_refptr<SharedContextState> context_state,
SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentationSkia(manager, backing, tracker),
gl_representation_(std::move(gl_representation)),
promise_texture_(std::move(promise_texture)),
context_state_(std::move(context_state)) {
DCHECK(gl_representation_);
#if DCHECK_IS_ON()
context_ = gl::GLContext::GetCurrent();
#endif
}
SharedImageRepresentationSkiaGL::~SharedImageRepresentationSkiaGL() {
DCHECK_EQ(RepresentationAccessMode::kNone, mode_);
surface_.reset();
}
sk_sp<SkSurface> SharedImageRepresentationSkiaGL::BeginWriteAccess(
int final_msaa_count,
const SkSurfaceProps& surface_props,
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores) {
DCHECK_EQ(mode_, RepresentationAccessMode::kNone);
CheckContext();
if (!gl_representation_->BeginAccess(
GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM)) {
return nullptr;
}
mode_ = RepresentationAccessMode::kWrite;
if (surface_)
return surface_;
SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType(
/*gpu_compositing=*/true, format());
// TODO(https://crbug.com/1054033): Switch back to
// MakeFromBackendTextureAsRenderTarget once we no longer use GLRendererCopier
// with surfaceless surfaces.
auto surface = SkSurface::MakeFromBackendTexture(
context_state_->gr_context(), promise_texture_->backendTexture(),
kTopLeft_GrSurfaceOrigin, final_msaa_count, sk_color_type,
backing()->color_space().ToSkColorSpace(), &surface_props);
surface_ = surface;
return surface;
}
void SharedImageRepresentationSkiaGL::EndWriteAccess(sk_sp<SkSurface> surface) {
DCHECK_EQ(mode_, RepresentationAccessMode::kWrite);
DCHECK(surface_);
DCHECK_EQ(surface.get(), surface_.get());
surface.reset();
DCHECK(surface_->unique());
gl_representation_->EndAccess();
mode_ = RepresentationAccessMode::kNone;
}
sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaGL::BeginReadAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores) {
DCHECK_EQ(mode_, RepresentationAccessMode::kNone);
CheckContext();
if (!gl_representation_->BeginAccess(
GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM)) {
return nullptr;
}
mode_ = RepresentationAccessMode::kRead;
return promise_texture_;
}
void SharedImageRepresentationSkiaGL::EndReadAccess() {
DCHECK_EQ(mode_, RepresentationAccessMode::kRead);
CheckContext();
gl_representation_->EndAccess();
mode_ = RepresentationAccessMode::kNone;
}
void SharedImageRepresentationSkiaGL::CheckContext() {
#if DCHECK_IS_ON()
DCHECK(gl::GLContext::GetCurrent() == context_);
#endif
}
bool SharedImageRepresentationSkiaGL::SupportsMultipleConcurrentReadAccess() {
return gl_representation_->SupportsMultipleConcurrentReadAccess();
}
} // namespace gpu