blob: 67c76c4c85836b79cf17dc131d47a382fc86f918 [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 "base/callback_helpers.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 "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 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(); }
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) {}
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(); }
};
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;
// 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() {}
};
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);
~ScopedWriteAccess();
SkSurface* surface() const { return surface_.get(); }
private:
sk_sp<SkSurface> surface_;
};
class GPU_GLES2_EXPORT ScopedReadAccess
: public ScopedAccessBase<SharedImageRepresentationSkia> {
public:
ScopedReadAccess(util::PassKey<SharedImageRepresentationSkia> pass_key,
SharedImageRepresentationSkia* representation,
sk_sp<SkPromiseImageTexture> promise_image_texture);
~ScopedReadAccess();
SkPromiseImageTexture* promise_image_texture() const {
return promise_image_texture_.get();
}
private:
sk_sp<SkPromiseImageTexture> promise_image_texture_;
};
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().
virtual sk_sp<SkSurface> BeginWriteAccess(
int final_msaa_count,
const SkSurfaceProps& surface_props,
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores) = 0;
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().
virtual sk_sp<SkPromiseImageTexture> BeginReadAccess(
std::vector<GrBackendSemaphore>* begin_semaphores,
std::vector<GrBackendSemaphore>* end_semaphores) = 0;
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;
};
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_REPRESENTATION_H_