1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef NATIVE_BUFFER_UTILS
17 #define NATIVE_BUFFER_UTILS
18 
19 #include <atomic>
20 
21 #include "native_buffer_inner.h"
22 #include "sync_fence.h"
23 #include "rs_vulkan_context.h"
24 #include "native_window.h"
25 #include "include/gpu/GrDirectContext.h"
26 #include "include/gpu/GrBackendSemaphore.h"
27 #include "include/core/SkSurface.h"
28 #include "draw/surface.h"
29 #include "image/image.h"
30 #include "drawing/engine_adapter/skia_adapter/skia_color_space.h"
31 
32 namespace OHOS::Rosen {
33 namespace NativeBufferUtils {
34 constexpr uint32_t VKIMAGE_LIMIT_SIZE = 10000 * 10000; // Vk-Image Size need less than 10000*10000
35 void DeleteVkImage(void* context);
36 class VulkanCleanupHelper {
37 public:
38     VulkanCleanupHelper(RsVulkanContext& vkContext, VkImage image, VkDeviceMemory memory,
39         const std::string& statName = "")
40         : fDevice_(vkContext.GetDevice()),
41           fImage_(image),
42           fMemory_(memory),
43           fDestroyImage_(vkContext.GetRsVulkanInterface().vkDestroyImage),
44           fFreeMemory_(vkContext.GetRsVulkanInterface().vkFreeMemory),
45           fStatName(statName),
46           fRefCnt_(1) {}
~VulkanCleanupHelper()47     ~VulkanCleanupHelper()
48     {
49         if (fStatName.length()) {
50             RsVulkanMemStat& memStat = RsVulkanContext::GetSingleton().GetRsVkMemStat();
51             memStat.DeleteResource(fStatName);
52         }
53         fDestroyImage_(fDevice_, fImage_, nullptr);
54         fFreeMemory_(fDevice_, fMemory_, nullptr);
55     }
56 
Ref()57     VulkanCleanupHelper* Ref()
58     {
59         (void)fRefCnt_.fetch_add(+1, std::memory_order_relaxed);
60         return this;
61     }
62 
UnRef()63     void UnRef()
64     {
65         if (fRefCnt_.fetch_add(-1, std::memory_order_acq_rel) == 1) {
66             delete this;
67         }
68     }
69 
70 private:
71     VkDevice fDevice_;
72     VkImage fImage_;
73     VkDeviceMemory fMemory_;
74     PFN_vkDestroyImage fDestroyImage_;
75     PFN_vkFreeMemory fFreeMemory_;
76     std::string fStatName;
77     mutable std::atomic<int32_t> fRefCnt_;
78 };
79 
80 struct NativeSurfaceInfo {
81     NativeSurfaceInfo() = default;
82     NativeSurfaceInfo(NativeSurfaceInfo &&) = default;
83     NativeSurfaceInfo &operator=(NativeSurfaceInfo &&) = default;
84     NativeSurfaceInfo(const NativeSurfaceInfo &) = delete;
85     NativeSurfaceInfo &operator=(const NativeSurfaceInfo &) = delete;
86 
87     NativeWindow* window = nullptr;
88     NativeWindowBuffer* nativeWindowBuffer = nullptr;
89     VkImage image = VK_NULL_HANDLE; // skia will destroy image
90     std::unique_ptr<SyncFence> fence = nullptr;
91     std::shared_ptr<Drawing::Surface> drawingSurface = nullptr;
92     int32_t lastPresentedCount = -1;
93     GraphicColorGamut graphicColorGamut = GRAPHIC_COLOR_GAMUT_INVALID;
~NativeSurfaceInfoNativeSurfaceInfo94     ~NativeSurfaceInfo()
95     {
96         drawingSurface = nullptr;
97         NativeObjectUnreference(window);
98         NativeObjectUnreference(nativeWindowBuffer);
99     }
100 };
101 
102 bool MakeFromNativeWindowBuffer(std::shared_ptr<Drawing::GPUContext> skContext, NativeWindowBuffer* nativeWindowBuffer,
103     NativeSurfaceInfo& nativeSurface, int width, int height, bool isProtected = false);
104 
105 Drawing::BackendTexture MakeBackendTextureFromNativeBuffer(NativeWindowBuffer* nativeWindowBuffer,
106     int width, int height, bool isProtected = false);
107 }
108 } // OHOS::Rosen
109 #endif