image_transfer_cache_entry.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // Copyright (c) 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef CC_PAINT_IMAGE_TRANSFER_CACHE_ENTRY_H_
  5. #define CC_PAINT_IMAGE_TRANSFER_CACHE_ENTRY_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <vector>
  9. #include "base/atomic_sequence_num.h"
  10. #include "base/containers/span.h"
  11. #include "base/memory/raw_ptr.h"
  12. #include "cc/paint/target_color_params.h"
  13. #include "cc/paint/transfer_cache_entry.h"
  14. #include "third_party/abseil-cpp/absl/types/optional.h"
  15. #include "third_party/skia/include/core/SkImageInfo.h"
  16. #include "third_party/skia/include/core/SkRefCnt.h"
  17. #include "third_party/skia/include/core/SkYUVAInfo.h"
  18. class GrDirectContext;
  19. class SkColorSpace;
  20. class SkImage;
  21. class SkPixmap;
  22. namespace cc {
  23. static constexpr uint32_t kInvalidImageTransferCacheEntryId =
  24. static_cast<uint32_t>(-1);
  25. enum class YUVDecodeFormat {
  26. kYUV3, // e.g., YUV 4:2:0, 4:2:2, or 4:4:4 as 3 planes.
  27. kYUVA4, // e.g., YUV 4:2:0 as 3 planes plus an alpha plane.
  28. kYVU3, // e.g., YVU 4:2:0, 4:2:2, or 4:4:4 as 3 planes.
  29. kYUV2, // e.g., YUV 4:2:0 as NV12 (2 planes).
  30. kUnknown,
  31. kMaxValue = kUnknown,
  32. };
  33. CC_PAINT_EXPORT size_t NumberOfPlanesForYUVDecodeFormat(YUVDecodeFormat format);
  34. // Client/ServiceImageTransferCacheEntry implement a transfer cache entry
  35. // for transferring image data. On the client side, this is a CPU SkPixmap,
  36. // on the service side the image is uploaded and is a GPU SkImage.
  37. class CC_PAINT_EXPORT ClientImageTransferCacheEntry final
  38. : public ClientTransferCacheEntryBase<TransferCacheEntryType::kImage> {
  39. public:
  40. ClientImageTransferCacheEntry(
  41. const SkPixmap* pixmap,
  42. bool needs_mips,
  43. absl::optional<TargetColorParams> target_color_params);
  44. ClientImageTransferCacheEntry(
  45. const SkPixmap yuva_pixmaps[],
  46. SkYUVAInfo::PlaneConfig plane_config,
  47. SkYUVAInfo::Subsampling subsampling,
  48. const SkColorSpace* decoded_color_space,
  49. SkYUVColorSpace yuv_color_space,
  50. bool needs_mips,
  51. absl::optional<TargetColorParams> target_color_params);
  52. ~ClientImageTransferCacheEntry() final;
  53. uint32_t Id() const final;
  54. // ClientTransferCacheEntry implementation:
  55. uint32_t SerializedSize() const final;
  56. bool Serialize(base::span<uint8_t> data) const final;
  57. static uint32_t GetNextId() { return s_next_id_.GetNext(); }
  58. bool IsYuv() const { return !!yuv_pixmaps_; }
  59. bool IsValid() const { return size_ > 0; }
  60. private:
  61. const bool needs_mips_ = false;
  62. absl::optional<TargetColorParams> target_color_params_;
  63. SkYUVAInfo::PlaneConfig plane_config_ = SkYUVAInfo::PlaneConfig::kUnknown;
  64. uint32_t id_;
  65. uint32_t size_ = 0;
  66. static base::AtomicSequenceNumber s_next_id_;
  67. // RGBX-only members.
  68. const raw_ptr<const SkPixmap> pixmap_;
  69. // YUVA-only members.
  70. absl::optional<std::array<const SkPixmap*, SkYUVAInfo::kMaxPlanes>>
  71. yuv_pixmaps_;
  72. const raw_ptr<const SkColorSpace> decoded_color_space_;
  73. SkYUVAInfo::Subsampling subsampling_ = SkYUVAInfo::Subsampling::kUnknown;
  74. SkYUVColorSpace yuv_color_space_;
  75. // DCHECKs that the appropriate data members are set or not set and have
  76. // positive size dimensions.
  77. void ValidateYUVDataBeforeSerializing() const;
  78. };
  79. class CC_PAINT_EXPORT ServiceImageTransferCacheEntry final
  80. : public ServiceTransferCacheEntryBase<TransferCacheEntryType::kImage> {
  81. public:
  82. ServiceImageTransferCacheEntry();
  83. ~ServiceImageTransferCacheEntry() final;
  84. ServiceImageTransferCacheEntry(ServiceImageTransferCacheEntry&& other);
  85. ServiceImageTransferCacheEntry& operator=(
  86. ServiceImageTransferCacheEntry&& other);
  87. // Populates this entry using the result of a hardware decode. The assumption
  88. // is that |plane_images| are backed by textures that are in turn backed by a
  89. // buffer (dmabuf in Chrome OS) containing the planes of the decoded image.
  90. // |plane_images_format| indicates the planar layout of |plane_images|.
  91. // |buffer_byte_size| is the size of the buffer. We assume the following:
  92. //
  93. // - The backing textures don't have mipmaps. We will generate the mipmaps if
  94. // |needs_mips| is true.
  95. // - The conversion from YUV to RGB will be performed according to
  96. // |yuv_color_space|.
  97. // - The colorspace of the resulting RGB image is sRGB.
  98. //
  99. // Returns true if the entry can be built, false otherwise.
  100. bool BuildFromHardwareDecodedImage(GrDirectContext* context,
  101. std::vector<sk_sp<SkImage>> plane_images,
  102. SkYUVAInfo::PlaneConfig plane_config,
  103. SkYUVAInfo::Subsampling subsampling,
  104. SkYUVColorSpace yuv_color_space,
  105. size_t buffer_byte_size,
  106. bool needs_mips);
  107. // ServiceTransferCacheEntry implementation:
  108. size_t CachedSize() const final;
  109. bool Deserialize(GrDirectContext* context,
  110. base::span<const uint8_t> data) final;
  111. bool fits_on_gpu() const { return fits_on_gpu_; }
  112. const std::vector<sk_sp<SkImage>>& plane_images() const {
  113. return plane_images_;
  114. }
  115. const sk_sp<SkImage>& image() const { return image_; }
  116. // Ensures the cached image has mips.
  117. void EnsureMips();
  118. bool has_mips() const { return has_mips_; }
  119. // Used in tests and for registering each texture for memory dumps.
  120. const sk_sp<SkImage>& GetPlaneImage(size_t index) const;
  121. const std::vector<size_t>& GetPlaneCachedSizes() const {
  122. return plane_sizes_;
  123. }
  124. bool is_yuv() const { return !plane_images_.empty(); }
  125. size_t num_planes() const {
  126. return is_yuv() ? SkYUVAInfo::NumPlanes(plane_config_) : 1u;
  127. }
  128. private:
  129. raw_ptr<GrDirectContext> context_ = nullptr;
  130. // The individual planes that are used by `image_` when `image_` is a YUVA
  131. // image. The planes are kept around for use in EnsureMips(), memory dumps,
  132. // and unit tests.
  133. std::vector<sk_sp<SkImage>> plane_images_;
  134. SkYUVAInfo::PlaneConfig plane_config_ = SkYUVAInfo::PlaneConfig::kUnknown;
  135. std::vector<size_t> plane_sizes_;
  136. sk_sp<SkImage> image_;
  137. absl::optional<SkYUVAInfo::Subsampling> subsampling_;
  138. absl::optional<SkYUVColorSpace> yuv_color_space_;
  139. bool has_mips_ = false;
  140. // The value of `size_` is computed during deserialization and never updated
  141. // (even if the size of the image changes due to mipmaps being requested).
  142. size_t size_ = 0;
  143. bool fits_on_gpu_ = false;
  144. };
  145. } // namespace cc
  146. #endif // CC_PAINT_IMAGE_TRANSFER_CACHE_ENTRY_H_