1 // Copyright 2019 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 5 #ifndef GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_BACKING_H_ 6 #define GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_BACKING_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/memory/scoped_refptr.h" 12 #include "base/util/type_safety/pass_key.h" 13 #include "components/viz/common/gpu/vulkan_context_provider.h" 14 #include "gpu/command_buffer/common/shared_image_usage.h" 15 #include "gpu/command_buffer/service/external_semaphore.h" 16 #include "gpu/command_buffer/service/external_semaphore_pool.h" 17 #include "gpu/command_buffer/service/shared_context_state.h" 18 #include "gpu/command_buffer/service/shared_image_backing.h" 19 #include "gpu/command_buffer/service/shared_memory_region_wrapper.h" 20 #include "gpu/command_buffer/service/texture_manager.h" 21 #include "gpu/vulkan/vulkan_device_queue.h" 22 #include "ui/gfx/gpu_memory_buffer.h" 23 24 namespace gpu { 25 26 class VulkanCommandPool; 27 class VulkanImage; 28 29 struct VulkanImageUsageCache { 30 // Maximal usage flags for VK_IMAGE_TILING_OPTIMAL each ResourceFormat. 31 VkImageUsageFlags optimal_tiling_usage[viz::RESOURCE_FORMAT_MAX + 1]; 32 }; 33 34 class ExternalVkImageBacking final : public ClearTrackingSharedImageBacking { 35 public: 36 static std::unique_ptr<ExternalVkImageBacking> Create( 37 scoped_refptr<SharedContextState> context_state, 38 VulkanCommandPool* command_pool, 39 const Mailbox& mailbox, 40 viz::ResourceFormat format, 41 const gfx::Size& size, 42 const gfx::ColorSpace& color_space, 43 GrSurfaceOrigin surface_origin, 44 SkAlphaType alpha_type, 45 uint32_t usage, 46 const VulkanImageUsageCache* image_usage_cache, 47 base::span<const uint8_t> pixel_data, 48 bool using_gmb = false); 49 50 static std::unique_ptr<ExternalVkImageBacking> CreateFromGMB( 51 scoped_refptr<SharedContextState> context_state, 52 VulkanCommandPool* command_pool, 53 const Mailbox& mailbox, 54 gfx::GpuMemoryBufferHandle handle, 55 gfx::BufferFormat buffer_format, 56 const gfx::Size& size, 57 const gfx::ColorSpace& color_space, 58 GrSurfaceOrigin surface_origin, 59 SkAlphaType alpha_type, 60 uint32_t usage, 61 const VulkanImageUsageCache* image_usage_cache); 62 63 ExternalVkImageBacking(util::PassKey<ExternalVkImageBacking>, 64 const Mailbox& mailbox, 65 viz::ResourceFormat format, 66 const gfx::Size& size, 67 const gfx::ColorSpace& color_space, 68 GrSurfaceOrigin surface_origin, 69 SkAlphaType alpha_type, 70 uint32_t usage, 71 scoped_refptr<SharedContextState> context_state, 72 std::unique_ptr<VulkanImage> image, 73 VulkanCommandPool* command_pool, 74 bool use_separate_gl_texture); 75 76 ~ExternalVkImageBacking() override; 77 context_state()78 SharedContextState* context_state() const { return context_state_.get(); } backend_texture()79 const GrBackendTexture& backend_texture() const { return backend_texture_; } image()80 VulkanImage* image() const { return image_.get(); } GetTexturePassthrough()81 const scoped_refptr<gles2::TexturePassthrough>& GetTexturePassthrough() 82 const { 83 return texture_passthrough_; 84 } context_provider()85 viz::VulkanContextProvider* context_provider() const { 86 return context_state()->vk_context_provider(); 87 } vulkan_implementation()88 VulkanImplementation* vulkan_implementation() const { 89 return context_provider()->GetVulkanImplementation(); 90 } fence_helper()91 VulkanFenceHelper* fence_helper() const { 92 return context_provider()->GetDeviceQueue()->GetFenceHelper(); 93 } external_semaphore_pool()94 ExternalSemaphorePool* external_semaphore_pool() { 95 return context_state()->external_semaphore_pool(); 96 } use_separate_gl_texture()97 bool use_separate_gl_texture() const { return use_separate_gl_texture_; } need_synchronization()98 bool need_synchronization() const { 99 if (usage() & SHARED_IMAGE_USAGE_WEBGPU) { 100 return true; 101 } 102 103 if (usage() & SHARED_IMAGE_USAGE_GLES2) { 104 return !use_separate_gl_texture() && (texture_ || texture_passthrough_); 105 } 106 107 if (usage() & SHARED_IMAGE_USAGE_SCANOUT) { 108 return true; 109 } 110 111 return false; 112 } reads_in_progress()113 uint32_t reads_in_progress() const { return reads_in_progress_; } gl_reads_in_progress()114 uint32_t gl_reads_in_progress() const { return gl_reads_in_progress_; } 115 116 // Notifies the backing that an access will start. Return false if there is 117 // currently any other conflict access in progress. Otherwise, returns true 118 // and semaphores which will be waited on before accessing. 119 bool BeginAccess(bool readonly, 120 std::vector<ExternalSemaphore>* external_semaphores, 121 bool is_gl); 122 123 // Notifies the backing that an access has ended. The representation must 124 // provide a semaphore handle that has been signaled at the end of the write 125 // access. 126 void EndAccess(bool readonly, 127 ExternalSemaphore external_semaphore, 128 bool is_gl); 129 130 // SharedImageBacking implementation. 131 void Update(std::unique_ptr<gfx::GpuFence> in_fence) override; 132 bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override; 133 scoped_refptr<gfx::NativePixmap> GetNativePixmap() override; 134 135 // Add semaphores to a pending list for reusing or being released immediately. 136 void AddSemaphoresToPendingListOrRelease( 137 std::vector<ExternalSemaphore> semaphores); 138 // Return |pending_semaphores_| and passed in |semaphores| to 139 // ExternalSemaphorePool for reusing. 140 void ReturnPendingSemaphoresWithFenceHelper( 141 std::vector<ExternalSemaphore> semaphores); 142 143 protected: 144 void UpdateContent(uint32_t content_flags); 145 bool BeginAccessInternal(bool readonly, 146 std::vector<ExternalSemaphore>* external_semaphores); 147 void EndAccessInternal(bool readonly, ExternalSemaphore external_semaphore); 148 149 // SharedImageBacking implementation. 150 std::unique_ptr<SharedImageRepresentationDawn> ProduceDawn( 151 SharedImageManager* manager, 152 MemoryTypeTracker* tracker, 153 WGPUDevice dawnDevice) override; 154 std::unique_ptr<SharedImageRepresentationGLTexture> ProduceGLTexture( 155 SharedImageManager* manager, 156 MemoryTypeTracker* tracker) override; 157 std::unique_ptr<SharedImageRepresentationGLTexturePassthrough> 158 ProduceGLTexturePassthrough(SharedImageManager* manager, 159 MemoryTypeTracker* tracker) override; 160 std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( 161 SharedImageManager* manager, 162 MemoryTypeTracker* tracker, 163 scoped_refptr<SharedContextState> context_state) override; 164 std::unique_ptr<SharedImageRepresentationOverlay> ProduceOverlay( 165 SharedImageManager* manager, 166 MemoryTypeTracker* tracker) override; 167 168 private: 169 // Install a shared memory GMB to the backing. 170 void InstallSharedMemory(SharedMemoryRegionWrapper shared_memory_wrapper); 171 // Returns texture_service_id for ProduceGLTexture and GLTexturePassthrough. 172 GLuint ProduceGLTextureInternal(); 173 174 using FillBufferCallback = base::OnceCallback<void(void* buffer)>; 175 // TODO(penghuang): Remove it when GrContext::updateBackendTexture() supports 176 // compressed texture and callback. 177 bool WritePixelsWithCallback(size_t data_size, 178 size_t stride, 179 FillBufferCallback callback); 180 bool WritePixelsWithData(base::span<const uint8_t> pixel_data, size_t stride); 181 bool WritePixels(); 182 void CopyPixelsFromGLTextureToVkImage(); 183 void CopyPixelsFromShmToGLTexture(); 184 185 scoped_refptr<SharedContextState> context_state_; 186 std::unique_ptr<VulkanImage> image_; 187 GrBackendTexture backend_texture_; 188 VulkanCommandPool* const command_pool_; 189 const bool use_separate_gl_texture_; 190 191 ExternalSemaphore write_semaphore_; 192 std::vector<ExternalSemaphore> read_semaphores_; 193 194 bool is_write_in_progress_ = false; 195 uint32_t reads_in_progress_ = 0; 196 uint32_t gl_reads_in_progress_ = 0; 197 gles2::Texture* texture_ = nullptr; 198 scoped_refptr<gles2::TexturePassthrough> texture_passthrough_; 199 200 // GMB related stuff. 201 SharedMemoryRegionWrapper shared_memory_wrapper_; 202 203 enum LatestContent { 204 kInVkImage = 1 << 0, 205 kInSharedMemory = 1 << 1, 206 kInGLTexture = 1 << 2, 207 }; 208 uint32_t latest_content_ = 0; 209 210 // Semaphores pending for returning to ExternalSemaphorePool. 211 // When the backing is accessed by the vulkan device for GrContext, they can 212 // be returned to ExternalSemaphorePool through VulkanFenceHelper. 213 std::vector<ExternalSemaphore> pending_semaphores_; 214 215 DISALLOW_COPY_AND_ASSIGN(ExternalVkImageBacking); 216 }; 217 218 } // namespace gpu 219 220 #endif // GPU_COMMAND_BUFFER_SERVICE_EXTERNAL_VK_IMAGE_BACKING_H_ 221