1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
  185
  186
  187
  188
  189
  190
  191
  192
  193
  194
  195
  196
  197
  198
  199
  200
  201
  202
  203
  204
  205
  206
  207
  208
  209
  210
  211
  212
  213
  214
  215
  216
  217
  218
  219
  220
  221
  222
  223
  224
  225
  226
  227
  228
  229
  230
  231
  232
  233
  234
  235
  236
  237

gpu / command_buffer / service / shared_image / shared_image_format_service_utils.h [blame]

// Copyright 2022 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_SHARED_IMAGE_FORMAT_SERVICE_UTILS_H_
#define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_FORMAT_SERVICE_UTILS_H_

#include "build/build_config.h"
#include "components/viz/common/resources/shared_image_format.h"
#include "gpu/command_buffer/common/gl2_types.h"
#include "gpu/config/gpu_preferences.h"
#include "gpu/gpu_gles2_export.h"
#include "gpu/vulkan/buildflags.h"
#include "skia/buildflags.h"
#include "third_party/dawn/include/dawn/webgpu.h"
#include "third_party/dawn/include/dawn/webgpu_cpp.h"
#include "third_party/skia/include/core/SkYUVAInfo.h"
#include "third_party/skia/include/gpu/graphite/TextureInfo.h"
#include "ui/gfx/buffer_types.h"

#if BUILDFLAG(ENABLE_VULKAN)
#include <vulkan/vulkan_core.h>
#endif

namespace skgpu::graphite {
class TextureInfo;
struct DawnTextureInfo;
}

namespace gpu {

struct VulkanYCbCrInfo;

namespace gles2 {
class FeatureInfo;
}  // namespace gles2

// GLFormatDesc is a struct containing the GL data type, data format, internal
// format used by the image, internal format used for storage and GL target.
struct GLFormatDesc {
  GLenum data_type = 0;
  GLenum data_format = 0;
  GLenum image_internal_format = 0;
  GLenum storage_internal_format = 0;
  GLenum target = 0;
};

// A set of utility functions to get the equivalent GPU API (GL, Vulkan, Dawn,
// Metal) type/format information for a given SharedImageFormat. These functions
// should ideally only be called from the GPU service and viz.

// BufferFormat is being transitioned out of SharedImage code (to use
// SharedImageFormat instead). Refrain from using this function or preferably
// use with single planar SharedImageFormats. Returns BufferFormat for given
// `format`.
GPU_GLES2_EXPORT gfx::BufferFormat ToBufferFormat(
    viz::SharedImageFormat format);

// Returns SkYUVAInfo::PlaneConfig equivalent of
// SharedImageFormat::PlaneConfig.
GPU_GLES2_EXPORT SkYUVAInfo::PlaneConfig ToSkYUVAPlaneConfig(
    viz::SharedImageFormat format);

// Returns SkYUVAInfo::Subsampling equivalent of
// SharedImageFormat::Subsampling.
GPU_GLES2_EXPORT SkYUVAInfo::Subsampling ToSkYUVASubsampling(
    viz::SharedImageFormat format);

// Returns the closest SkColorType for a given multiplanar `format` with
// external sampler.
GPU_GLES2_EXPORT SkColorType
ToClosestSkColorTypeExternalSampler(viz::SharedImageFormat format);

// Holds capabilities and provides accessors for getting appropriate GL formats
// for shared images.
class GPU_GLES2_EXPORT GLFormatCaps {
 public:
  // For default values of feature info capabilities.
  GLFormatCaps() = default;
  explicit GLFormatCaps(const gles2::FeatureInfo* feature_info);

  // Following functions return the appropriate GL type/format for a
  // SharedImageFormat.
  // Return the GLFormatDesc when using external sampler for a given `format`.
  GLFormatDesc ToGLFormatDescExternalSampler(
      viz::SharedImageFormat format) const;
  // Return the GLFormatDesc for a given `format`.
  GLFormatDesc ToGLFormatDesc(viz::SharedImageFormat format,
                              int plane_index) const;
  // Same as above with an additional param to control whether to use
  // HALF_FLOAT_OES extension types or core types for F16 format.
  GLFormatDesc ToGLFormatDescOverrideHalfFloatType(
      viz::SharedImageFormat format,
      int plane_index) const;

  bool ext_texture_rg() const { return ext_texture_rg_; }
  bool ext_texture_norm16() const { return ext_texture_norm16_; }
  bool disable_r8_shared_images() const { return disable_r8_shared_images_; }
  bool enable_texture_half_float_linear() const {
    return enable_texture_half_float_linear_;
  }
  bool is_atleast_gles3() const { return is_atleast_gles3_; }

 private:
  // Return fallback gl format if the GL data, internal, tex storage format is
  // not supported.
  GLenum GetFallbackFormatIfNotSupported(GLenum gl_format) const;

  bool angle_rgbx_internal_format_ = false;
  bool oes_texture_float_available_ = false;
  bool ext_texture_rg_ = false;
  bool ext_texture_norm16_ = false;
  bool disable_r8_shared_images_ = false;
  bool enable_texture_half_float_linear_ = false;
  bool is_atleast_gles3_ = false;
};

// Following functions return the appropriate Vulkan format for a
// SharedImageFormat.
#if BUILDFLAG(ENABLE_VULKAN)
// Returns true if given `format` is supported by Vulkan.
GPU_GLES2_EXPORT bool HasVkFormat(viz::SharedImageFormat format);
// Returns vulkan format for given `format` with external sampler.
GPU_GLES2_EXPORT VkFormat
ToVkFormatExternalSampler(viz::SharedImageFormat format);
// Returns vulkan format for given `format`, which must be single-planar.
GPU_GLES2_EXPORT VkFormat ToVkFormatSinglePlanar(viz::SharedImageFormat format);
// Returns vulkan format for given `format`, which can be single-planar or
// multiplanar with per-plane sampling.
GPU_GLES2_EXPORT VkFormat ToVkFormat(viz::SharedImageFormat format,
                                     int plane_index);
#endif

// Following functions return the appropriate Dawn format for a
// SharedImageFormat. Returns wgpu::TextureFormat format for given `format`.
// Note that this will return a multi-planar Dawn format for multi-planar
// SharedImageFormat.
GPU_GLES2_EXPORT wgpu::TextureFormat ToDawnFormat(
    viz::SharedImageFormat format);
// Returns wgpu::TextureFormat format for given `format` and `plane_index`. Note
// that this returns a single plane Dawn format i.e the TextureView format and
// not a multi-planar format.
// NOTE: This should not be used on Android when using YCbCr sampling, as in
// that case wgpu::TextureFormat::EXTERNAL must be used.
GPU_GLES2_EXPORT wgpu::TextureFormat ToDawnTextureViewFormat(
    viz::SharedImageFormat format,
    int plane_index);

// Returns the supported Dawn texture usage. `is_yuv_plane` indicates if the
// texture corresponds to a plane of a multi-planar image and `is_dcomp_surface`
// indicates if the texture corresponds to a direct composition surface.
// `supports_multiplanar_rendering` indicates if the dawn texture supports
// drawing to multiplanar render targets.
wgpu::TextureUsage SupportedDawnTextureUsage(
    viz::SharedImageFormat format,
    bool is_yuv_plane,
    bool is_dcomp_surface,
    bool supports_multiplanar_rendering,
    bool supports_multiplanar_copy);

// Returns wgpu::TextureAspect corresponding to `plane_index`. `is_yuv_plane`
// indicates if the aspect corresponds to a plane of a multi-planar
// wgpu::Texture.
wgpu::TextureAspect ToDawnTextureAspect(bool is_yuv_plane, int plane_index);

// Following function return the appropriate Metal format for a
// SharedImageFormat.
#if BUILDFLAG(IS_APPLE)
// Returns MtlPixelFormat format for given `format`.
GPU_GLES2_EXPORT unsigned int ToMTLPixelFormat(viz::SharedImageFormat format,
                                               int plane_index = 0);
// Return the expected four character code pixel format for an IOSurface with
// the specified format.
GPU_GLES2_EXPORT uint32_t
SharedImageFormatToIOSurfacePixelFormat(viz::SharedImageFormat format,
                                        bool override_rgba_to_bgra);
#endif

// Returns the graphite::TextureInfo for a given `format` and `plane_index`.
// `is_yuv_plane` indicates if the texture corresponds to a plane of a
// multi-planar image. `mipmapped` indicates if the texture has mipmaps.
// `scanout_dcomp_surface` indicates if the texture corresponds to a Windows
// direct composition surface. `supports_multiplanar_rendering` indicates if the
// dawn texture supports drawing to multiplanar render targets.
// `supports_multiplanar_copy` indicates if the dawn backend supports copy
// operations for multiplanar textures.
GPU_GLES2_EXPORT skgpu::graphite::TextureInfo GraphiteBackendTextureInfo(
    GrContextType gr_context_type,
    viz::SharedImageFormat format,
    bool readonly,
    int plane_index,
    bool is_yuv_plane,
    bool mipmapped,
    bool scanout_dcomp_surface,
    bool supports_multiplanar_rendering,
    bool supports_multiplanar_copy);

GPU_GLES2_EXPORT skgpu::graphite::TextureInfo GraphitePromiseTextureInfo(
    GrContextType gr_context_type,
    viz::SharedImageFormat format,
    std::optional<VulkanYCbCrInfo> ycbcr_info,
    int plane_index = 0,
    bool mipmapped = false);

#if BUILDFLAG(ENABLE_VULKAN) && BUILDFLAG(SKIA_USE_DAWN)
GPU_GLES2_EXPORT wgpu::YCbCrVkDescriptor ToDawnYCbCrVkDescriptor(
    const VulkanYCbCrInfo& ycbcr_info);
#endif

#if BUILDFLAG(SKIA_USE_DAWN)
GPU_GLES2_EXPORT skgpu::graphite::DawnTextureInfo DawnBackendTextureInfo(
    viz::SharedImageFormat format,
    bool readonly,
    bool is_yuv_plane,
    int plane_index,
    int array_slice,
    bool mipmapped,
    bool scanout_dcomp_surface,
    bool supports_multiplanar_rendering,
    bool support_multiplanar_copy);
#endif

#if BUILDFLAG(SKIA_USE_METAL)
GPU_GLES2_EXPORT skgpu::graphite::TextureInfo GraphiteMetalTextureInfo(
    viz::SharedImageFormat format,
    int plane_index = 0,
    bool is_yuv_plane = false,
    bool mipmapped = false);
#endif

GPU_GLES2_EXPORT
skgpu::graphite::TextureInfo FallbackGraphiteBackendTextureInfo(
    const skgpu::graphite::TextureInfo& texture_info);

}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_FORMAT_SERVICE_UTILS_H_