blob: 5c7d414491207ca1d64deb79f89caa26dcb91fc7 [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.
#ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_H_
#define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_H_
#include <dawn/dawn_proc_table.h>
#include <dawn/webgpu.h>
#include <memory>
#include "base/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/util/type_safety/pass_key.h"
#include "build/build_config.h"
#include "components/viz/common/resources/resource_format.h"
#include "gpu/command_buffer/service/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image_manager.h"
#include "gpu/gpu_gles2_export.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrBackendSurfaceMutableState.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/gpu_fence.h"
typedef unsigned int GLenum;
class SkPromiseImageTexture;
namespace gl {
class GLImage;
}
namespace gfx {
class NativePixmap;
} // namespace gfx
namespace media {
class VASurface;
} // namespace media
namespace gpu {
class TextureBase;
namespace gles2 {
class Texture;
class TexturePassthrough;
} // namespace gles2
enum class RepresentationAccessMode {
kNone,
kRead,
kWrite,
};
// A representation of a SharedImageBacking for use with a specific use case /
// api.
class GPU_GLES2_EXPORT SharedImageRepresentation {
public:
// Used by derived classes.
enum class AllowUnclearedAccess { kYes, kNo };
SharedImageRepresentation(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker);
virtual ~SharedImageRepresentation();
viz::ResourceFormat format() const { return backing_->format(); }
const gfx::Size& size() const { return backing_->size(); }
const gfx::ColorSpace& color_space() const { return backing_->color_space(); }
uint32_t usage() const { return backing_->usage(); }
const gpu::Mailbox& mailbox() const { return backing_->mailbox(); }
MemoryTypeTracker* tracker() { return tracker_; }
bool IsCleared() const { return backing_->IsCleared(); }
void SetCleared() { backing_->SetCleared(); }
gfx::Rect ClearedRect() const { return backing_->ClearedRect(); }
void SetClearedRect(const gfx::Rect& cleared_rect) {
backing_->SetClearedRect(cleared_rect);
}
// Indicates that the underlying graphics context has been lost, and the
// backing should be treated as destroyed.
void OnContextLost() {
has_context_ = false;
backing_->OnContextLost();
}
protected:
SharedImageManager* manager() const { return manager_; }
SharedImageBacking* backing() const { return backing_; }
bool has_context() const { return has_context_; }
// Helper class for derived classes' Scoped*Access objects. Has tracking to
// ensure a Scoped*Access does not outlive the representation it's associated
// with.
template <typename RepresentationClass>
class ScopedAccessBase {
public:
ScopedAccessBase(RepresentationClass* representation)
: representation_(representation) {
DCHECK(!representation_->has_scoped_access_);
representation_->has_scoped_access_ = true;
}
~ScopedAccessBase() {
DCHECK(representation_->has_scoped_access_);
representation_->has_scoped_access_ = false;
}
RepresentationClass* representation() { return representation_; }
private:
RepresentationClass* const representation_;
DISALLOW_COPY_AND_ASSIGN(ScopedAccessBase);
};
private:
SharedImageManager* const manager_;
SharedImageBacking* const backing_;
MemoryTypeTracker* const tracker_;
bool has_context_ = true;
bool has_scoped_access_ = false;
};
class SharedImageRepresentationFactoryRef : public SharedImageRepresentation {
public:
SharedImageRepresentationFactoryRef(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {}
~SharedImageRepresentationFactoryRef() override;
const Mailbox& mailbox() const { return backing()->mailbox(); }
void Update(std::unique_ptr<gfx::GpuFence> in_fence) {
backing()->Update(std::move(in_fence));
backing()->OnWriteSucceeded();
}
bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) {
return backing()->ProduceLegacyMailbox(mailbox_manager);
}
bool PresentSwapChain() { return backing()->PresentSwapChain(); }
void RegisterImageFactory(SharedImageFactory* factory) {
backing()->RegisterImageFactory(factory);
}
};
class GPU_GLES2_EXPORT SharedImageRepresentationGLTextureBase
: public SharedImageRepresentation {
public:
class ScopedAccess
: public ScopedAccessBase<SharedImageRepresentationGLTextureBase> {
public:
ScopedAccess(util::PassKey<SharedImageRepresentationGLTextureBase> pass_key,
SharedImageRepresentationGLTextureBase* representation)
: ScopedAccessBase(representation) {}
~ScopedAccess() {
representation()->UpdateClearedStateOnEndAccess();
representation()->EndAccess();
}
};
SharedImageRepresentationGLTextureBase(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {}
std::unique_ptr<ScopedAccess> BeginScopedAccess(
GLenum mode,
AllowUnclearedAccess allow_uncleared);
virtual gpu::TextureBase* GetTextureBase() = 0;
protected:
friend class SharedImageRepresentationSkiaGL;
friend class SharedImageRepresentationGLTextureImpl;
// Can be overridden to handle clear state tracking when GL access begins or
// ends.
virtual void UpdateClearedStateOnBeginAccess() {}
virtual void UpdateClearedStateOnEndAccess() {}
// TODO(ericrk): Make these pure virtual and ensure real implementations
// exist.
virtual bool BeginAccess(GLenum mode);
virtual void EndAccess() {}
virtual bool SupportsMultipleConcurrentReadAccess();
};
class GPU_GLES2_EXPORT SharedImageRepresentationGLTexture
: public SharedImageRepresentationGLTextureBase {
public:
SharedImageRepresentationGLTexture(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentationGLTextureBase(manager, backing, tracker) {}
// TODO(ericrk): Move this to the ScopedAccess object. crbug.com/1003686
virtual gles2::Texture* GetTexture() = 0;
gpu::TextureBase* GetTextureBase() override;
protected:
void UpdateClearedStateOnBeginAccess() override;
void UpdateClearedStateOnEndAccess() override;
};
class GPU_GLES2_EXPORT SharedImageRepresentationGLTexturePassthrough
: public SharedImageRepresentationGLTextureBase {
public:
SharedImageRepresentationGLTexturePassthrough(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentationGLTextureBase(manager, backing, tracker) {}
// TODO(ericrk): Move this to the ScopedAccess object. crbug.com/1003686
virtual const scoped_refptr<gles2::TexturePassthrough>&
GetTexturePassthrough() = 0;
gpu::TextureBase* GetTextureBase() override;
};
class GPU_GLES2_EXPORT SharedImageRepresentationSkia
: public SharedImageRepresentation {
public:
class GPU_GLES2_EXPORT ScopedWriteAccess
: public ScopedAccessBase<SharedImageRepresentationSkia> {
public:
ScopedWriteAccess(util::PassKey<SharedImageRepresentationSkia> pass_key,
SharedImageRepresentationSkia* representation,
sk_sp<SkSurface> surface,
std::unique_ptr<GrBackendSurfaceMutableState> end_state);
~ScopedWriteAccess();
SkSurface* surface() const { return surface_.get(); }
GrBackendSurfaceMutableState* end_state() const { return end_state_.get(); }
private:
sk_sp<SkSurface> surface_;
std::unique_ptr<GrBackendSurfaceMutableState> end_state_;
};
class GPU_GLES2_EXPORT ScopedReadAccess
: public ScopedAccessBase<SharedImageRepresentationSkia> {
public:
ScopedReadAccess(util::PassKey<SharedImageRepresentationSkia> pass_key,
SharedImageRepresentationSkia* representation,
sk_sp<SkPromiseImageTexture> promise_image_texture,
std::unique_ptr<GrBackendSurfaceMutableState> end_state);
~ScopedReadAccess();
SkPromiseImageTexture* promise_image_texture() const {
return promise_image_texture_.get();
}
GrBackendSurfaceMutableState* end_state() const { return end_state_.get(); }
private:
sk_sp<SkPromiseImageTexture> promise_image_texture_;
std::unique_ptr<GrBackendSurfaceMutableState> end_state_;
};
SharedImageRepresentationSkia(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {}
// Note: See BeginWriteAccess below for a description of the semaphore
// parameters.
std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess(
int final_msaa_count,
const SkSurfaceProps& surface_props,
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores,
AllowUnclearedAccess allow_uncleared);
std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores,
AllowUnclearedAccess allow_uncleared);
// Note: See BeginReadAccess below for a description of the semaphore
// parameters.
std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores);
virtual bool SupportsMultipleConcurrentReadAccess();
protected:
// Begin the write access. The implementations should insert semaphores into
// begin_semaphores vector which client will wait on before writing the
// backing. The ownership of begin_semaphores will be passed to client.
// The implementations should also insert semaphores into end_semaphores,
// client must submit them with drawing operations which use the backing.
// The ownership of end_semaphores are not passed to client. And client must
// submit the end_semaphores before calling EndWriteAccess().
// The backing can assign end_state, and the caller must reset backing's state
// to the end_state before calling EndWriteAccess().
virtual sk_sp<SkSurface> BeginWriteAccess(
int final_msaa_count,
const SkSurfaceProps& surface_props,
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores,
std::unique_ptr<GrBackendSurfaceMutableState>* end_state);
virtual sk_sp<SkSurface> BeginWriteAccess(
int final_msaa_count,
const SkSurfaceProps& surface_props,
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores);
virtual void EndWriteAccess(sk_sp<SkSurface> surface) = 0;
// Begin the read access. The implementations should insert semaphores into
// begin_semaphores vector which client will wait on before reading the
// backing. The ownership of begin_semaphores will be passed to client.
// The implementations should also insert semaphores into end_semaphores,
// client must submit them with drawing operations which use the backing.
// The ownership of end_semaphores are not passed to client. And client must
// submit the end_semaphores before calling EndReadAccess().
// The backing can assign end_state, and the caller must reset backing's state
// to the end_state before calling EndReadAccess().
virtual sk_sp<SkPromiseImageTexture> BeginReadAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores,
std::unique_ptr<GrBackendSurfaceMutableState>* end_state);
virtual sk_sp<SkPromiseImageTexture> BeginReadAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores);
virtual void EndReadAccess() = 0;
};
class GPU_GLES2_EXPORT SharedImageRepresentationDawn
: public SharedImageRepresentation {
public:
SharedImageRepresentationDawn(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {}
class GPU_GLES2_EXPORT ScopedAccess
: public ScopedAccessBase<SharedImageRepresentationDawn> {
public:
ScopedAccess(util::PassKey<SharedImageRepresentationDawn> pass_key,
SharedImageRepresentationDawn* representation,
WGPUTexture texture);
~ScopedAccess();
WGPUTexture texture() const { return texture_; }
private:
WGPUTexture texture_ = 0;
};
// Calls BeginAccess and returns a ScopedAccess object which will EndAccess
// when it goes out of scope. The Representation must outlive the returned
// ScopedAccess.
std::unique_ptr<ScopedAccess> BeginScopedAccess(
WGPUTextureUsage usage,
AllowUnclearedAccess allow_uncleared);
private:
// This can return null in case of a Dawn validation error, for example if
// usage is invalid.
virtual WGPUTexture BeginAccess(WGPUTextureUsage usage) = 0;
virtual void EndAccess() = 0;
};
class GPU_GLES2_EXPORT SharedImageRepresentationOverlay
: public SharedImageRepresentation {
public:
SharedImageRepresentationOverlay(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {}
class ScopedReadAccess
: public ScopedAccessBase<SharedImageRepresentationOverlay> {
public:
ScopedReadAccess(util::PassKey<SharedImageRepresentationOverlay> pass_key,
SharedImageRepresentationOverlay* representation,
gl::GLImage* gl_image);
~ScopedReadAccess() { representation()->EndReadAccess(); }
gl::GLImage* gl_image() const {
return gl_image_;
}
private:
gl::GLImage* gl_image_;
};
#if defined(OS_ANDROID)
virtual void NotifyOverlayPromotion(bool promotion,
const gfx::Rect& bounds) = 0;
#endif
std::unique_ptr<ScopedReadAccess> BeginScopedReadAccess(bool needs_gl_image);
protected:
// TODO(weiliangc): Currently this only handles Android pre-SurfaceControl
// case. Add appropriate fence later.
virtual bool BeginReadAccess() = 0;
virtual void EndReadAccess() = 0;
// TODO(weiliangc): Add API to backing AHardwareBuffer.
// TODO(penghuang): Refactor it to not depend on GL.
// Get the backing as GLImage for GLSurface::ScheduleOverlayPlane.
virtual gl::GLImage* GetGLImage() = 0;
};
// An interface that allows a SharedImageBacking to hold a reference to VA-API
// surface without depending on //media/gpu/vaapi targets.
class VaapiDependencies {
public:
virtual ~VaapiDependencies() = default;
virtual const media::VASurface* GetVaSurface() const = 0;
virtual bool SyncSurface() = 0;
};
// Interface that allows a SharedImageBacking to create VaapiDependencies from a
// NativePixmap without depending on //media/gpu/vaapi targets.
class VaapiDependenciesFactory {
public:
virtual ~VaapiDependenciesFactory() = default;
// Returns a VaapiDependencies or nullptr on failure.
virtual std::unique_ptr<VaapiDependencies> CreateVaapiDependencies(
scoped_refptr<gfx::NativePixmap> pixmap) = 0;
};
// Representation of a SharedImageBacking as a VA-API surface.
// This representation is currently only supported by SharedImageBackingOzone.
//
// Synchronized access is currently not required in this representation because:
//
// For reads:
// We will be using this for the destination of decoding work, so no read access
// synchronization is needed from the point of view of the VA-API.
//
// For writes:
// Because of the design of the current video pipeline, we don't start the
// decoding work until we're sure that the destination buffer is not being used
// by the rest of the pipeline. However, we still need to keep track of write
// accesses so that other representations can synchronize with the decoder.
class GPU_GLES2_EXPORT SharedImageRepresentationVaapi
: public SharedImageRepresentation {
public:
class GPU_GLES2_EXPORT ScopedWriteAccess
: public ScopedAccessBase<SharedImageRepresentationVaapi> {
public:
ScopedWriteAccess(util::PassKey<SharedImageRepresentationVaapi> pass_key,
SharedImageRepresentationVaapi* representation);
~ScopedWriteAccess();
const media::VASurface* va_surface();
};
SharedImageRepresentationVaapi(SharedImageManager* manager,
SharedImageBacking* backing,
MemoryTypeTracker* tracker,
VaapiDependencies* vaapi_dependency);
~SharedImageRepresentationVaapi() override;
std::unique_ptr<ScopedWriteAccess> BeginScopedWriteAccess();
private:
VaapiDependencies* vaapi_deps_;
virtual void EndAccess() = 0;
virtual void BeginAccess() = 0;
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_H_