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 RS_SURFACE_OHOS_VULKAN_H
17 #define RS_SURFACE_OHOS_VULKAN_H
18 
19 #include <cstdint>
20 
21 #include <list>
22 #include <unordered_map>
23 #include "native_window.h"
24 #include "vulkan/vulkan_core.h"
25 #include "platform/ohos/backend/rs_vulkan_context.h"
26 #include "sync_fence.h"
27 #include "native_buffer_utils.h"
28 #include "image/image.h"
29 #include "platform/ohos/rs_surface_ohos.h"
30 #include "rs_surface_frame_ohos_vulkan.h"
31 #include <surface.h>
32 
33 namespace OHOS {
34 namespace Rosen {
35 struct DestroySemaphoreInfo {
36     PFN_vkDestroySemaphore mDestroyFunction;
37     VkDevice mDevice;
38     VkSemaphore mSemaphore;
39 
40     int mRefs = 2;
DestroySemaphoreInfoDestroySemaphoreInfo41     DestroySemaphoreInfo(PFN_vkDestroySemaphore destroyFunction, VkDevice device,
42                         VkSemaphore semaphore)
43         : mDestroyFunction(destroyFunction), mDevice(device), mSemaphore(semaphore) {}
44 
DestroySemaphoreDestroySemaphoreInfo45     static void DestroySemaphore(void *context)
46     {
47         if (context == nullptr) {
48             return;
49         }
50         DestroySemaphoreInfo* info = reinterpret_cast<DestroySemaphoreInfo*>(context);
51         --info->mRefs;
52         if (!info->mRefs) {
53             info->mDestroyFunction(info->mDevice, info->mSemaphore, nullptr);
54             delete info;
55         }
56     }
57 };
58 
59 class RSSurfaceOhosVulkan : public RSSurfaceOhos {
60 public:
61     explicit RSSurfaceOhosVulkan(const sptr<Surface>& producer);
62     ~RSSurfaceOhosVulkan() override;
63 
IsValid()64     bool IsValid() const override
65     {
66         return producer_ != nullptr;
67     }
68 
69     std::unique_ptr<RSSurfaceFrame> RequestFrame(
70         int32_t width, int32_t height, uint64_t uiTimestamp, bool useAFBC = true, bool isProtected = false) override;
71     bool FlushFrame(std::unique_ptr<RSSurfaceFrame>& frame, uint64_t uiTimestamp) override;
72     void SetColorSpace(GraphicColorGamut colorSpace) override;
73     void SetSurfaceBufferUsage(uint64_t usage) override;
74     void SetSurfacePixelFormat(int32_t pixelFormat) override;
75     sptr<SurfaceBuffer> GetCurrentBuffer() override;
76     void ClearBuffer() override;
77     void ResetBufferAge() override;
78     void SetUiTimeStamp(const std::unique_ptr<RSSurfaceFrame>& frame, uint64_t uiTimestamp) override;
SetSkContext(std::shared_ptr<Drawing::GPUContext> skContext)79     void SetSkContext(std::shared_ptr<Drawing::GPUContext> skContext)
80     {
81         mSkContext = skContext;
82     }
WaitSurfaceClear()83     void WaitSurfaceClear()
84     {
85         if (mSkContext) {
86             mSkContext->FlushAndSubmit(true);
87         }
88         mSurfaceMap.clear();
89     }
90     int DupReservedFlushFd();
91 private:
92     struct NativeWindow* mNativeWindow = nullptr;
93     int mWidth = -1;
94     int mHeight = -1;
95     int mReservedFlushFd = -1;
96     void SetNativeWindowInfo(int32_t width, int32_t height, bool useAFBC, bool isProtected = false);
97     int32_t mPresentCount = 0;
98     std::list<NativeWindowBuffer*> mSurfaceList;
99     std::list<uint32_t> mSurfaceList2;
100     std::unordered_map<uint32_t, NativeBufferUtils::NativeSurfaceInfo> mSurfaceMap2;
101     std::unordered_map<NativeWindowBuffer*, NativeBufferUtils::NativeSurfaceInfo> mSurfaceMap;
102     std::shared_ptr<Drawing::GPUContext> mSkContext = nullptr;
103     int32_t RequestNativeWindowBuffer(NativeWindowBuffer** nativeWindowBuffer,
104         int32_t width, int32_t height, int& fenceFd, bool useAFBC, bool isProtected = false);
105     void CreateVkSemaphore(VkSemaphore& semaphore,
106         RsVulkanContext& vkContext, NativeBufferUtils::NativeSurfaceInfo& nativeSurface);
107 };
108 
109 } // namespace Rosen
110 } // namespace OHOS
111 
112 #endif // RS_SURFACE_OHOS_VULKAN_H
113