xref: /aosp_15_r20/frameworks/base/libs/hwui/renderthread/VulkanSurface.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker #pragma once
17*d57664e9SAndroid Build Coastguard Worker 
18*d57664e9SAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
19*d57664e9SAndroid Build Coastguard Worker #include <system/graphics.h>
20*d57664e9SAndroid Build Coastguard Worker #include <system/window.h>
21*d57664e9SAndroid Build Coastguard Worker #include <vulkan/vulkan.h>
22*d57664e9SAndroid Build Coastguard Worker 
23*d57664e9SAndroid Build Coastguard Worker #include <SkColorSpace.h>
24*d57664e9SAndroid Build Coastguard Worker #include <SkRefCnt.h>
25*d57664e9SAndroid Build Coastguard Worker #include <SkSize.h>
26*d57664e9SAndroid Build Coastguard Worker 
27*d57664e9SAndroid Build Coastguard Worker #include "IRenderPipeline.h"
28*d57664e9SAndroid Build Coastguard Worker 
29*d57664e9SAndroid Build Coastguard Worker class SkSurface;
30*d57664e9SAndroid Build Coastguard Worker 
31*d57664e9SAndroid Build Coastguard Worker namespace android {
32*d57664e9SAndroid Build Coastguard Worker namespace uirenderer {
33*d57664e9SAndroid Build Coastguard Worker namespace renderthread {
34*d57664e9SAndroid Build Coastguard Worker 
35*d57664e9SAndroid Build Coastguard Worker class VulkanManager;
36*d57664e9SAndroid Build Coastguard Worker 
37*d57664e9SAndroid Build Coastguard Worker class VulkanSurface {
38*d57664e9SAndroid Build Coastguard Worker public:
39*d57664e9SAndroid Build Coastguard Worker     static VulkanSurface* Create(ANativeWindow* window, ColorMode colorMode, SkColorType colorType,
40*d57664e9SAndroid Build Coastguard Worker                                  sk_sp<SkColorSpace> colorSpace, GrDirectContext* grContext,
41*d57664e9SAndroid Build Coastguard Worker                                  const VulkanManager& vkManager, uint32_t extraBuffers);
42*d57664e9SAndroid Build Coastguard Worker     ~VulkanSurface();
43*d57664e9SAndroid Build Coastguard Worker 
getCurrentSkSurface()44*d57664e9SAndroid Build Coastguard Worker     sk_sp<SkSurface> getCurrentSkSurface() {
45*d57664e9SAndroid Build Coastguard Worker         return mCurrentBufferInfo ? mCurrentBufferInfo->skSurface : nullptr;
46*d57664e9SAndroid Build Coastguard Worker     }
getCurrentPreTransform()47*d57664e9SAndroid Build Coastguard Worker     const SkMatrix& getCurrentPreTransform() { return mWindowInfo.preTransform; }
48*d57664e9SAndroid Build Coastguard Worker 
49*d57664e9SAndroid Build Coastguard Worker     void setColorSpace(sk_sp<SkColorSpace> colorSpace);
getPixelSnapMatrix()50*d57664e9SAndroid Build Coastguard Worker     const SkM44& getPixelSnapMatrix() const { return mWindowInfo.pixelSnapMatrix; }
51*d57664e9SAndroid Build Coastguard Worker 
52*d57664e9SAndroid Build Coastguard Worker private:
53*d57664e9SAndroid Build Coastguard Worker     /*
54*d57664e9SAndroid Build Coastguard Worker      * All structs/methods in this private section are specifically for use by the VulkanManager
55*d57664e9SAndroid Build Coastguard Worker      *
56*d57664e9SAndroid Build Coastguard Worker      */
57*d57664e9SAndroid Build Coastguard Worker     friend VulkanManager;
58*d57664e9SAndroid Build Coastguard Worker     struct NativeBufferInfo {
59*d57664e9SAndroid Build Coastguard Worker         sk_sp<SkSurface> skSurface;
60*d57664e9SAndroid Build Coastguard Worker         sp<ANativeWindowBuffer> buffer;
61*d57664e9SAndroid Build Coastguard Worker         // The fence is only valid when the buffer is dequeued, and should be
62*d57664e9SAndroid Build Coastguard Worker         // -1 any other time. When valid, we own the fd, and must ensure it is
63*d57664e9SAndroid Build Coastguard Worker         // closed: either by closing it explicitly when queueing the buffer,
64*d57664e9SAndroid Build Coastguard Worker         // or by passing ownership e.g. to ANativeWindow::cancelBuffer().
65*d57664e9SAndroid Build Coastguard Worker         base::unique_fd dequeue_fence;
66*d57664e9SAndroid Build Coastguard Worker         bool dequeued = false;
67*d57664e9SAndroid Build Coastguard Worker         uint32_t lastPresentedCount = 0;
68*d57664e9SAndroid Build Coastguard Worker         bool hasValidContents = false;
69*d57664e9SAndroid Build Coastguard Worker     };
70*d57664e9SAndroid Build Coastguard Worker 
71*d57664e9SAndroid Build Coastguard Worker     NativeBufferInfo* dequeueNativeBuffer();
getCurrentBufferInfo()72*d57664e9SAndroid Build Coastguard Worker     NativeBufferInfo* getCurrentBufferInfo() { return mCurrentBufferInfo; }
73*d57664e9SAndroid Build Coastguard Worker     bool presentCurrentBuffer(const SkRect& dirtyRect, int semaphoreFd);
74*d57664e9SAndroid Build Coastguard Worker 
75*d57664e9SAndroid Build Coastguard Worker     // The width and height are are the logical width and height for when submitting draws to the
76*d57664e9SAndroid Build Coastguard Worker     // surface. In reality if the window is rotated the underlying window may have the width and
77*d57664e9SAndroid Build Coastguard Worker     // height swapped.
logicalWidth()78*d57664e9SAndroid Build Coastguard Worker     int logicalWidth() const { return mWindowInfo.size.width(); }
logicalHeight()79*d57664e9SAndroid Build Coastguard Worker     int logicalHeight() const { return mWindowInfo.size.height(); }
80*d57664e9SAndroid Build Coastguard Worker     int getCurrentBuffersAge();
81*d57664e9SAndroid Build Coastguard Worker 
82*d57664e9SAndroid Build Coastguard Worker private:
83*d57664e9SAndroid Build Coastguard Worker     /*
84*d57664e9SAndroid Build Coastguard Worker      * All code below this line while logically available to VulkanManager should not be treated
85*d57664e9SAndroid Build Coastguard Worker      * as private to this class.
86*d57664e9SAndroid Build Coastguard Worker      *
87*d57664e9SAndroid Build Coastguard Worker      */
88*d57664e9SAndroid Build Coastguard Worker 
89*d57664e9SAndroid Build Coastguard Worker     // How many buffers we want to be able to use ourselves. We want 1 in active rendering with
90*d57664e9SAndroid Build Coastguard Worker     // 1 more queued, so 2. This will be added to NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, which is
91*d57664e9SAndroid Build Coastguard Worker     // how many buffers the consumer needs (eg, 1 for SurfaceFlinger), getting to a typically
92*d57664e9SAndroid Build Coastguard Worker     // triple-buffered queue as a result.
93*d57664e9SAndroid Build Coastguard Worker     static constexpr uint32_t sTargetBufferCount = 2;
94*d57664e9SAndroid Build Coastguard Worker 
95*d57664e9SAndroid Build Coastguard Worker     struct WindowInfo {
96*d57664e9SAndroid Build Coastguard Worker         SkISize size;
97*d57664e9SAndroid Build Coastguard Worker         uint32_t bufferFormat;
98*d57664e9SAndroid Build Coastguard Worker         android_dataspace dataspace;
99*d57664e9SAndroid Build Coastguard Worker         sk_sp<SkColorSpace> colorspace;
100*d57664e9SAndroid Build Coastguard Worker         ColorMode colorMode;
101*d57664e9SAndroid Build Coastguard Worker         int transform;
102*d57664e9SAndroid Build Coastguard Worker         size_t bufferCount;
103*d57664e9SAndroid Build Coastguard Worker         uint64_t windowUsageFlags;
104*d57664e9SAndroid Build Coastguard Worker 
105*d57664e9SAndroid Build Coastguard Worker         // size of the ANativeWindow if the inverse of transform requires us to swap width/height
106*d57664e9SAndroid Build Coastguard Worker         SkISize actualSize;
107*d57664e9SAndroid Build Coastguard Worker         // transform to be applied to the SkSurface to map the coordinates to the provided transform
108*d57664e9SAndroid Build Coastguard Worker         SkMatrix preTransform;
109*d57664e9SAndroid Build Coastguard Worker         SkM44 pixelSnapMatrix;
110*d57664e9SAndroid Build Coastguard Worker     };
111*d57664e9SAndroid Build Coastguard Worker 
112*d57664e9SAndroid Build Coastguard Worker     VulkanSurface(ANativeWindow* window, const WindowInfo& windowInfo, GrDirectContext* grContext);
113*d57664e9SAndroid Build Coastguard Worker     static bool InitializeWindowInfoStruct(ANativeWindow* window, ColorMode colorMode,
114*d57664e9SAndroid Build Coastguard Worker                                            SkColorType colorType, sk_sp<SkColorSpace> colorSpace,
115*d57664e9SAndroid Build Coastguard Worker                                            const VulkanManager& vkManager, uint32_t extraBuffers,
116*d57664e9SAndroid Build Coastguard Worker                                            WindowInfo* outWindowInfo);
117*d57664e9SAndroid Build Coastguard Worker     static bool UpdateWindow(ANativeWindow* window, const WindowInfo& windowInfo);
118*d57664e9SAndroid Build Coastguard Worker     void releaseBuffers();
119*d57664e9SAndroid Build Coastguard Worker     void invalidateBuffers();
120*d57664e9SAndroid Build Coastguard Worker 
121*d57664e9SAndroid Build Coastguard Worker     // TODO: This number comes from ui/BufferQueueDefs. We're not pulling the
122*d57664e9SAndroid Build Coastguard Worker     // header in so that we don't need to depend on libui, but we should share
123*d57664e9SAndroid Build Coastguard Worker     // this constant somewhere. But right now it's okay to keep here because we
124*d57664e9SAndroid Build Coastguard Worker     // can't safely change the slot count anyways.
125*d57664e9SAndroid Build Coastguard Worker     static constexpr size_t kNumBufferSlots = 64;
126*d57664e9SAndroid Build Coastguard Worker     // TODO: Just use a vector?
127*d57664e9SAndroid Build Coastguard Worker     NativeBufferInfo mNativeBuffers[kNumBufferSlots];
128*d57664e9SAndroid Build Coastguard Worker 
129*d57664e9SAndroid Build Coastguard Worker     sp<ANativeWindow> mNativeWindow;
130*d57664e9SAndroid Build Coastguard Worker     WindowInfo mWindowInfo;
131*d57664e9SAndroid Build Coastguard Worker     GrDirectContext* mGrContext;
132*d57664e9SAndroid Build Coastguard Worker 
133*d57664e9SAndroid Build Coastguard Worker     uint32_t mPresentCount = 0;
134*d57664e9SAndroid Build Coastguard Worker     NativeBufferInfo* mCurrentBufferInfo = nullptr;
135*d57664e9SAndroid Build Coastguard Worker };
136*d57664e9SAndroid Build Coastguard Worker 
137*d57664e9SAndroid Build Coastguard Worker } /* namespace renderthread */
138*d57664e9SAndroid Build Coastguard Worker } /* namespace uirenderer */
139*d57664e9SAndroid Build Coastguard Worker } /* namespace android */
140