910e62b5创建于 1月15日历史提交
// Copyright 2019 The Chromium Authors
// 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_EGL_IMAGE_BACKING_H_
#define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_EGL_IMAGE_BACKING_H_

#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "gpu/command_buffer/service/shared_image/gl_common_image_backing_factory.h"
#include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/scoped_egl_image.h"

namespace gl {
class GLFenceEGL;
class SharedGLFenceEGL;
}  // namespace gl

namespace gpu {
class GpuDriverBugWorkarounds;
struct Mailbox;

// Implementation of SharedImageBacking that is used to create EGLImage targets
// from the same EGLImage object. Hence all the representations created from
// this backing uses EGL Image siblings. This backing is thread safe across
// different threads running different GL contexts not part of same shared
// group. This is achieved by using locks and fences for proper synchronization.
class EGLImageBacking : public ClearTrackingSharedImageBacking {
 public:
  EGLImageBacking(
      const Mailbox& mailbox,
      viz::SharedImageFormat format,
      const gfx::Size& size,
      const gfx::ColorSpace& color_space,
      GrSurfaceOrigin surface_origin,
      SkAlphaType alpha_type,
      gpu::SharedImageUsageSet usage,
      std::string debug_label,
      size_t estimated_size,
      const std::vector<GLCommonImageBackingFactory::FormatInfo>& format_into,
      const GpuDriverBugWorkarounds& workarounds,
      bool use_passthrough,
      base::span<const uint8_t> pixel_data);

  EGLImageBacking(const EGLImageBacking&) = delete;
  EGLImageBacking& operator=(const EGLImageBacking&) = delete;

  ~EGLImageBacking() override;

  // SharedImageBacking implementation.
  SharedImageBackingType GetType() const override;
  void Update(std::unique_ptr<gfx::GpuFence> in_fence) override;
  void MarkForDestruction() override;

 protected:
  std::unique_ptr<GLTextureImageRepresentation> ProduceGLTexture(
      SharedImageManager* manager,
      MemoryTypeTracker* tracker) override;

  std::unique_ptr<GLTexturePassthroughImageRepresentation>
  ProduceGLTexturePassthrough(SharedImageManager* manager,
                              MemoryTypeTracker* tracker) override;

  std::unique_ptr<SkiaGaneshImageRepresentation> ProduceSkiaGanesh(
      SharedImageManager* manager,
      MemoryTypeTracker* tracker,
      scoped_refptr<SharedContextState> context_state) override;

  std::unique_ptr<DawnImageRepresentation> ProduceDawn(
      SharedImageManager* manager,
      MemoryTypeTracker* tracker,
      const wgpu::Device& device,
      wgpu::BackendType backend_type,
      std::vector<wgpu::TextureFormat> view_formats,
      scoped_refptr<SharedContextState> context_state) final;

 private:
  class TextureHolder;
  class GLRepresentationShared;
  class GLTextureEGLImageRepresentation;
  class GLTexturePassthroughEGLImageRepresentation;

  template <class T>
  std::unique_ptr<T> ProduceGLTextureInternal(SharedImageManager* manager,
                                              MemoryTypeTracker* tracker);

  bool BeginWrite();
  void EndWrite();
  bool BeginRead(const GLRepresentationShared* reader);
  void EndRead(const GLRepresentationShared* reader);

  // Use to create EGLImage texture target from the same EGLImage object.
  // Optional |pixel_data| to initialize a texture with before EGLImage object
  // is created from it.
  gl::ScopedEGLImage GenEGLImageSibling(base::span<const uint8_t> pixel_data,
                                        std::vector<GLuint>& service_ids,
                                        int plane);
  std::vector<scoped_refptr<TextureHolder>> GenEGLImageSiblings(
      base::span<const uint8_t> pixel_data);

  const std::vector<GLCommonImageBackingFactory::FormatInfo> format_info_;
  std::vector<scoped_refptr<TextureHolder>> source_texture_holders_;
  raw_ptr<gl::GLApi> created_on_context_;

  std::vector<gl::ScopedEGLImage> egl_images_ GUARDED_BY(lock_);

  // All reads and writes must wait for exiting writes to complete.
  // TODO(vikassoni): Use SharedGLFenceEGL here instead of GLFenceEGL here in
  // future for |write_fence_| once the SharedGLFenceEGL has the capability to
  // support multiple GLContexts.
  std::unique_ptr<gl::GLFenceEGL> write_fence_ GUARDED_BY(lock_);
  bool is_writing_ GUARDED_BY(lock_) = false;

  // All writes must wait for existing reads to complete. For a given GL
  // context, we only need to keep the most recent fence. Waiting on the most
  // recent read fence is enough to make sure all past read fences have been
  // signalled.
  base::flat_map<gl::GLApi*, scoped_refptr<gl::SharedGLFenceEGL>> read_fences_
      GUARDED_BY(lock_);
  base::flat_set<raw_ptr<const GLRepresentationShared, CtnExperimental>>
      active_readers_ GUARDED_BY(lock_);

  const bool use_passthrough_;
};

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_EGL_IMAGE_BACKING_H_