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