• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "src/gpu/ganesh/vk/GrVkSamplerYcbcrConversion.h"
9 
10 #include "include/gpu/vk/VulkanTypes.h"
11 #include "include/private/base/SkAssert.h"
12 #include "src/gpu/ganesh/vk/GrVkCaps.h"
13 #include "src/gpu/ganesh/vk/GrVkGpu.h"
14 #include "src/gpu/ganesh/vk/GrVkUtil.h"
15 #include "src/gpu/vk/VulkanUtilsPriv.h"
16 
Create(GrVkGpu * gpu,const skgpu::VulkanYcbcrConversionInfo & info)17 GrVkSamplerYcbcrConversion* GrVkSamplerYcbcrConversion::Create(
18         GrVkGpu* gpu, const skgpu::VulkanYcbcrConversionInfo& info) {
19     if (!gpu->vkCaps().supportsYcbcrConversion()) {
20         return nullptr;
21     }
22 
23     VkSamplerYcbcrConversionCreateInfo ycbcrCreateInfo;
24     skgpu::SetupSamplerYcbcrConversionInfo(&ycbcrCreateInfo, info);
25 
26 #ifdef SK_BUILD_FOR_ANDROID
27     VkExternalFormatANDROID externalFormat;
28     if (info.fExternalFormat) {
29         // Format must not be specified for external images.
30         SkASSERT(info.fFormat == VK_FORMAT_UNDEFINED);
31         externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
32         externalFormat.pNext = nullptr;
33         externalFormat.externalFormat = info.fExternalFormat;
34         SkASSERT(ycbcrCreateInfo.pNext == nullptr);
35         ycbcrCreateInfo.pNext = &externalFormat;
36     }
37 #elif defined(VK_USE_PLATFORM_OHOS)
38     VkExternalFormatOHOS externalFormat;
39     if (info.fExternalFormat) {
40         // Format must not be specified for external images.
41         SkASSERT(info.fFormat == VK_FORMAT_UNDEFINED);
42         externalFormat.sType = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_OHOS;
43         externalFormat.pNext = nullptr;
44         externalFormat.externalFormat = info.fExternalFormat;
45         ycbcrCreateInfo.pNext = &externalFormat;
46     }
47 #else
48     // External images are supported only on Android/OpenHarmony.
49     SkASSERT(!info.fExternalFormat);
50 #endif
51 
52     if (!info.fExternalFormat) {
53         SkASSERT(info.fFormat != VK_FORMAT_UNDEFINED);
54     }
55 
56     VkSamplerYcbcrConversion conversion;
57     VkResult result;
58     GR_VK_CALL_RESULT(gpu, result, CreateSamplerYcbcrConversion(gpu->device(), &ycbcrCreateInfo,
59                                                                 nullptr, &conversion));
60     if (result != VK_SUCCESS) {
61         return nullptr;
62     }
63 
64     return new GrVkSamplerYcbcrConversion(gpu, conversion, GenerateKey(info));
65 }
66 
freeGPUData() const67 void GrVkSamplerYcbcrConversion::freeGPUData() const {
68     SkASSERT(fYcbcrConversion);
69     GR_VK_CALL(fGpu->vkInterface(), DestroySamplerYcbcrConversion(fGpu->device(),
70                                                                   fYcbcrConversion, nullptr));
71 }
72 
GenerateKey(const skgpu::VulkanYcbcrConversionInfo & ycbcrInfo)73 GrVkSamplerYcbcrConversion::Key GrVkSamplerYcbcrConversion::GenerateKey(
74         const skgpu::VulkanYcbcrConversionInfo& ycbcrInfo) {
75     SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrModel <= 7));
76     static const int kRangeShift = 3;
77     SkASSERT(static_cast<int>(ycbcrInfo.fYcbcrRange) <= 1);
78     static const int kXChromaOffsetShift = kRangeShift + 1;
79     SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
80     static const int kYChromaOffsetShift = kXChromaOffsetShift + 1;
81     SkASSERT(static_cast<int>(ycbcrInfo.fXChromaOffset) <= 1);
82     static const int kChromaFilterShift = kYChromaOffsetShift + 1;
83     SkASSERT(static_cast<int>(ycbcrInfo.fChromaFilter) <= 1);
84     static const int kReconShift = kChromaFilterShift + 1;
85     SkASSERT(static_cast<int>(ycbcrInfo.fForceExplicitReconstruction) <= 1);
86     static const int kCompRShift = kReconShift + 1;
87     static const int kCompGShift = kCompRShift + 3;
88     static const int kCompBShift = kCompGShift + 3;
89     static const int kCompAShift = kCompBShift + 3;
90     SkASSERT(static_cast<int>(ycbcrInfo.fComponents.r <= 6) &&
91              static_cast<int>(ycbcrInfo.fComponents.g <= 6) &&
92              static_cast<int>(ycbcrInfo.fComponents.b <= 6) &&
93              static_cast<int>(ycbcrInfo.fComponents.a <= 6));
94     static_assert(kCompAShift <= 17);
95 
96     uint32_t ycbcrKey = static_cast<uint32_t>(ycbcrInfo.fYcbcrModel);
97     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fYcbcrRange) << kRangeShift);
98     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fXChromaOffset) << kXChromaOffsetShift);
99     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fYChromaOffset) << kYChromaOffsetShift);
100     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fChromaFilter) << kChromaFilterShift);
101     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fForceExplicitReconstruction) << kReconShift);
102     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.r) << kCompRShift);
103     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.g) << kCompGShift);
104     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.b) << kCompBShift);
105     ycbcrKey |= (static_cast<uint32_t>(ycbcrInfo.fComponents.a) << kCompAShift);
106 
107     return Key{ycbcrInfo.fFormat, ycbcrInfo.fExternalFormat, ycbcrKey};
108 }
109